JDBC学习笔记(二)

  • 分页实现

1.数据的支持:MySQL LIMIT M,N M:记录开始索引。第一条记录的的索引是0 N:每次查询出的记录条数

假设有customers表 一次取10条: 第一页:SELECT * FROM customers LIMIT 0,10; 第二页:SELECT * FROM customers LIMIT 10,10; 第n页: SELECT * FROM customers LIMIT (n-1)*10,10;

总页数 总页数:总记录条数%10==0?总记录条数/10:总记录条数/10+1;

  • 具体的分页代码

screenshot

当当前页面小于等于6时候,保持原来的不变

screenshot

当前页面大于6的时候,是另外的情况,开始下标变为当前下标-5,结束下标是当前页面+4

 1 public Page{
 2 	//以谷歌搜索引擎的分页为例
 3 	private List records;//存放分页记录
 4 	
 5 	private currentPageNum;//当前页码
 6 	private totalPage;	   //总页数
 7 	private pageSize =10;  //每页显示的记录条数
 8 	
 9 	private int totalRecords;//总记录条数
10 	private int startIndex;	 //每页记录开始的索引
11 	
12 	private int prePageNum;	 //上一页
13 	private int nextPageNum; //下一页
14 	
15 	private int startPage;	//开始页码
16 	private int endPage;	//结束页码
17 	
18 	private String uri;		//查询分页的网址
19 	
20 	public Page(int currentPageNum,int totalRecords){
21 		this.currentPageNum = currentPageNum;
22 		this.totalRecords = totalRecords;
23 		
24 		//计算总页数
25 		totalPage = totalRecords%pageSize==
26 		0?totalRecords/pageSize:totalRecords/pageSize+1;
27 		//计算每页开始的索引
28 		startIndex=(currentPageNum-1)*pageSize;
29 		
30 		//总页数大于10 进行分页处理
31 		if(totalPage>10){
32 			startPage = currentPageNum - 5;
33 			endPage = currentPageNum + 4;
34 			
35 			if(startPage < 1){
36 				startPage = 1;
37 				endPage = 10;
38 			}
39 			if(endPage > totalPage){
40 				startPage = totalPage -9;
41 				endPage = totalPage;				
42 			}
43 		}else{
44 			startPage = 1;
45 			endPage = totalPage;
46 		}
47 	}
48 	
49 }
  • 接下来是改造服务层和dao层 这里不做赘述
  •  批处理
     1 	//插入2条数据,删除第一条。批处理
     2 	/*
     3 	create database test;
     4 	use test;
     5 	create table t1(
     6 		id int primary key,
     7 		name varchar(100)
     8 	);
     9 	 */
    10 	//如果批处理执行的语句不相同,最好使用Statement
    11 	//方法 用statement创建的对象中的addBatch方法
    12 	//       executeBatch返回数组
    13 	//       增强for循环进行遍历
    14 	public void test1(){
    15 		Connection conn = null;
    16 		Statement stmt =  null;
    17 		try{
    18 			conn = JdbcUtil.getConnection();//JdbcUtil的实现在上一篇中有提到
    19 			stmt = conn.createStatement();//内部有一个List,就是sql语句的缓存
    20 			
    21 			String sql1 = "insert into t1 (id,name) values(1,'aa1')";
    22 			String sql2 = "insert into t1 (id,name) values(2,'aa2')";
    23 			String sql3 = "delete from t1 where id=1";
    24 			
    25 			stmt.addBatch(sql1);		
    26 			stmt.addBatch(sql2);
    27 			stmt.addBatch(sql3);
    28 			
    29 			int [] ii = stmt.executeBatch();//批处理.每条语句影响的行数
    30 			
    31 			for(int i:ii)
    32 				System.out.println(i);
    33 		}catch(Exception e){
    34 			e.printStackTrace();
    35 		}finally{
    36 			JdbcUtil.release(null, stmt, conn);
    37 		}
    38 	}
    

如果使用_PrepareStatement_一次影响多条数据时

 1 
 2 	//方法 用PrepareStatement创建的对象中的addBatch方法
 3 	//       隔1000次进行一个清空缓存 利用clearBatch方法
 4 	//       executeBatch返回数组
 5 	//       增强for循环进行遍历
 6 	//插入100001条记录
 7 	@Test
 8 	public void test3(){
 9 		Connection conn = null;
10 		PreparedStatement stmt =  null;
11 		try{
12 			conn = JdbcUtil.getConnection();
13 			stmt = conn.prepareStatement("insert into t1 (id,name) values(?,?)");
14 			
15 			for(int i=0;i<100001;i++){
16 				stmt.setInt(1, i+1);
17 				stmt.setString(2, "aa"+(i+1));
18 				stmt.addBatch();//向缓存中加的参数
19 				if(i%1000==0){
20 					stmt.executeBatch();// 执行一次
21 					stmt.clearBatch();//清空缓存中的内容
22 				}
23 			}
24 			
25 			stmt.executeBatch();//批处理.每条语句影响的行数
26 			
27 		}catch(Exception e){
28 			e.printStackTrace();
29 		}finally{
30 			JdbcUtil.release(null, stmt, conn);
31 		}
32 	}
  • 大对象的存储(非重点) 1.LOB:Large Object CLOB:Character Large Object 大文本 BLOB:Binary Large Object 图片 视频 声音 等 2.MySQL支持的LOB类型 可变长度类型 TINYBLOB, TINYTEXT 256B BLOB, TEXT 64K MEDIUMBLOB, MEDIUMTEXT 16M LONGBLOB, LONGTEXT 4G
  • 插入大文本数据和取出文本数据 ```java 1 public class LobDemo{ 2 //插入大文本数据 3 @Test 4 public void testTextWrite() throws Exception{ 5 Connection conn = JdbcUtil.getConnection(); 6 PreparedStatement stmt = conn.PreparedStatement(“insert into t2 (id,content) values (?,?)”); 7 stmt.setInt(1,1); 8 9 File file = new File(“路径”); 10 Reader reader = new FileReader(file); 11 stmt.setCharacterStream(2,reader,(int)file.length());//第一个参数插入的参数个数 12 13 stmt.executeUpdate(); 14 15 JdbcUtil.release(null,stmt,conn); 16 17 } 18

1 public class LobDemo{ 2 //取出大文本数据 3 @Test 4 public void testTextRead() throws Exception{ 5 Connection conn = JdbcUtil.getConnection(); 6 PreparedStatement stmt = new PreparedStatement(“select * from t2 where id=1”); 7 ResultSet rs = stmt.executeUpdate(); 8 if(rs.next()){ 9 Reader r = rs.getCharacter(“Content”); 10 //写到磁盘上 11 Write w = new FileWriter(“写到的路径”); 12 char c[] = new char[1024]; 13 int len = -1; 14 while((len=r.read(c)!=-1){ 15 w.write(c,0,len); 16 } 17 r.close(); 18 w.close(); 19 } 20 JdbcUtil.release(); 21 } 22 }

- 插入二进制文本和取出二进制文本
```java
 1 	//插入大二进制数据
 2 	@Test
 3 	public void testBlobWrite() throws Exception{
 4 		Connection conn = JdbcUtil.getConnection();
 5 		PreparedStatement stmt = conn.prepareStatement("insert into t3 (id,content) values (?,?)");
 6 		stmt.setInt(1, 1);
 7 		InputStream in = new FileInputStream("src/19.jpg");
 8 		stmt.setBinaryStream(2, in, in.available());
 9 		
10 		stmt.executeUpdate();
11 		
12 		JdbcUtil.release(null, stmt, conn);
13 	}
14 	//取出大二进制数据
15 	@Test
16 	public void testBlobRead() throws Exception{
17 		Connection conn = JdbcUtil.getConnection();
18 		PreparedStatement stmt = conn.prepareStatement("select * from t3 where id=1");
19 		ResultSet rs = stmt.executeQuery();
20 		if(rs.next()){
21 			InputStream in = rs.getBinaryStream("content");
22 			//写到磁盘上
23 			OutputStream out = new FileOutputStream("d:/a.jpg");
24 			byte b[] = new byte[1024];
25 			int len = -1;
26 			while((len=in.read(b))!=-1){
27 				out.write(b, 0, len);
28 			}
29 			in.close();
30 			out.close();
31 		}
32 		
33 		JdbcUtil.release(rs, stmt, conn);
34 	}
  • 事务的入门 ```java _start transaction:_开启事务 _rollback:_回滚事务 _commit:_提交事务

1 //JDBC中的事务实现 2 public void test1(){ 3 Connection conn = null; 4 PreparedStatement stmt = null; 5 6 try{ 7 conn = JdbcUtil.getConnection(); 8 conn.setAutoCommit(false); //开启事务 9 10 stmt = conn.PreparedStatement(“update account set money = money + 100 where name=’aaa’”); 11 stmt.execteUpdate(); 12 13 stmt = conn.PreparedStatement(“update account set money = money - 100 where name=’bbb’”); 14 stmt.execteUpdate(); 15 16 conn.commit(); 17 }catch(Exception e){ 18 if(conn == null){ 19 try{ 20 conn.rollback(); 21 }catch(SQLException e1){ 22 e1.printStackTrace(); 23 } 24 } 25 e.printStackTrace(); 26 } 27 } ```

  • 事务的特性

原子性:指处于同一个事务中的多条语句是不可分割的。 一致性:事务必须使数据库从一个一致性状态变换到另外一个一致性状态。比如,转账,转                   账前两个账户余额之和为2K,转账之后也应该是2K。 隔离性:指多线程环境下,一个线程中的事务不能被其他线程中的事务打扰 持久性:事务一旦提交,就应该被永久保存起来。

  • 事务的隔离性 如果不考虑隔离性会出现以下的问题

脏读:指一个线程中的事务读取到了另外一个线程中未提交的数据。 不可重复读:指一个线程中的事务读取到了另外一个线程中提交的_update_的数据。 虚读:指一个线程中的事务读取到了另外一个线程中提交的_insert_的数据。

  • 隔离级别

1:READ UNCOMMITTED:脏读、不可重复读、虚读都有可能发生。 2:READ COMMITTED:防止脏读的发生,不可重复读、虚读都有可能发生。 4:REPEATABLE READ:防止脏读、不可重复读的发生,虚读有可能发生。 8:SERIALIZABLE:防止脏读、不可重复读、虚读的发生。

MySQL: 查看当前事务的隔离级别:SELECT @@tx_isolation; 更改事务的隔离级别:(注意:一定要在开启事务之前设定) SET transaction isolation level 四个级别之一(单词);

尝试:

screenshot

                                                                                                            查理   2017.5.26




    Enjoy Reading This Article?

    Here are some more articles you might like to read next:

  • What is Mathematics: Solution Chapter 3
  • What is Mathematics: Solution Chapter 2
  • What is Mathematics: Solution Chapter 1
  • A small guide to supplements: What you need to know
  • 混乱与秩序