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;
- 具体的分页代码
当当前页面小于等于6时候,保持原来的不变
当前页面大于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 四个级别之一(单词);
尝试:
查理 2017.5.26
Enjoy Reading This Article?
Here are some more articles you might like to read next: