增强JDBC

来源:互联网 发布:java文件上传 编辑:程序博客网 时间:2024/05/17 07:06

在这里,主要介绍三个部分:

  1. JDBC批处理。
  2. JDBC处理大数据
  3. 数据库事务

JDBC批处理
  前面我们说了JDBC是一套接口,是为了实现用java代码去操作数据库所存在的,但前面说的全是一次只能发送一条语句,在初期你可能觉得无所谓,那么如果需要在员工表中插入2000条数据呢?难道要去操作2000次?这是不可能的,效率太低了。为了解决这一问题,java中又引入了一些新的概念——JDBC批处理。
  这里先介绍一些相关的API:
  

 Statement批处理:    void addBatch(String sql)  添加sql到缓存区(暂时不发送)    int[] executeBatch() 执行批处理命令。 发送所有缓存区的sql    void clearBatch()  清空sql缓存区PreparedStatement批处理:           void addBatch() 添加参数到缓存区    int[] executeBatch() 执行批处理命令。 发送所有缓存区的sql    void clearBatch()  清空sql缓存区使用两个参数的prepareStatement()方法,指定可以返回自动增长的键值    Statement.RETURN_GENERATED_KEYS: 可以返回自动增长值    Statement.NO_GENERATED_KEYS: 不能返回自动增长值

JDBC处理大数据
  
  数据库不仅能存储数据,也可以存储文档、图片、视频等各种文件,和数据表比起来他们所占的内存无疑是巨大的,所以这边给出了一些大容量的字段。
  

字符:
  存储字符内容: mysql: char(0-255) varchar(0-65535) 长度有限的。 65535
  大容量的字符字段:
   mysql: text(64K) longtext(4G字符内容)
   oracle : clob longclob
字节:
  mysql: blob(65kb) mediumblob(16mb) longblog(4GB)
  oracle: blob

数据库事务   
  什么是事物呢?所谓的事务,如果把多条sql语句看做一个事务,那么这个事务要么一起成功,要么一起失败!!
  关于数据库事务,有一个典型的案例——模拟银行转账
  

1.张三和李四各自都存有5000元钱
2.张三向李四转了2000元,自己剩3000元
3.李四收到2000元,自己有7000元
但是,如果在张三转账后系统故障,在java中第三步也就不会进行,那么导致的结果就是张三的确是3000元,丹李四却只有5000元,转出去的2000元不见了。

Java针对这种情况,提出了事物概念,下面是一些相关的API方法:

mysql事务操作命令    set autocommit =0 / 1;          设置是否自动提交事务        1: 表示自动提交事务,每执行一条sql语句,自动提交事务。        0: 表示关闭自动提交事务。    commit;           提交事务,一旦提交事务不能回滚    rollback;           回滚事务。回滚到事务的起始点。jdbc事务操作    Connection.setAutoCommit(false)  开启事务    Connection.commit();  成功执行,最后提交事务    Connection.rollback();  一旦遇到错误,回滚事务

事物的四大特性:

原子性: 要么一起成功过,要么一起失败
一致性: 数据库应该从一个一致性的状态到另一个一致性的状态,保持不变
隔离性: 多个并发事务直接应该可以相互隔离
持久性: 事务一旦提交,应该永久保持下来。

这里是代码演示:
1.批处理

package com.thz_statement_batch;import java.sql.Connection;import java.sql.PreparedStatement;import com.thz_jdbc_util.JDBCUtil;public class Test {    public static void main(String[] args) {        //批处理发送sql语句        testPreparedStatementBatch();    }    private static void testPreparedStatementBatch() {        Connection conn = null;        PreparedStatement stmt = null;        try{            conn  = JDBCUtil.getConn();            //创建一个动态的sql语句            String sql  = "insert into stu values(?,?);";            stmt = conn.prepareStatement(sql);            //型数据库插入2000条数据,一次插入一条            for (int i = 1; i <=2000; i++) {                stmt.setInt(1, i);                stmt.setString(2, "刘德华");                stmt.addBatch();                //判断每20条发送一次                if (i%20==0) {                    stmt.executeBatch();                    //清空缓存区                    stmt.clearBatch();                }            }        }catch(Exception e){            e.printStackTrace();        }finally{            //释放资源            JDBCUtil.close(conn, stmt, null);        }    }}package com.thz_preparedstatement_batch;import java.sql.Connection;import java.sql.Statement;import com.thz_jdbc_util.JDBCUtil;public class Test {    public static void main(String[] args) {        //使用批处理的情况下,给学生表中插入2000条数据        testStatementBatch();    }    private static void testStatementBatch() {        Connection conn  =null;        Statement stmt = null;        try{            //获取连接            conn = JDBCUtil.getConn();            //获取statement对象            stmt = conn.createStatement();            //每次给stmt这个命令行中添加20条sql语句,一次性进行发送            for (int i = 1; i <=2000; i++) {                String sql  = "insert into stu values("+i+",'刘德华');";                //将这个sql先暂时添加在stmt的命令行中                stmt.addBatch(sql);                if (i%20==0) {                    //批量发送sql                    stmt.executeBatch();                    //清空stmt的命令行列表                    stmt.clearBatch();                }            }        }catch(Exception e){            e.printStackTrace();        }finally{            //释放资源            JDBCUtil.close(conn, stmt, null);        }    }}

2、大数据,注意:在存储图片、视频等文件时用字节流不要用字符流

package com.thz_jdbc_clob;import java.io.FileReader;import java.io.FileWriter;import java.io.Reader;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import com.thz_jdbc_util.JDBCUtil;public class ClobDemo {    public static void main(String[] args) {        //需求:将一篇文章存储到数据库中        //write();        read();    }    private static void read() {        Connection conn = null;        PreparedStatement stmt = null;        ResultSet rs = null;        try{            //获取连接            conn  = JDBCUtil.getConn();            String sql = "select * from news";            stmt = conn.prepareStatement(sql);            //执行sql             rs = stmt.executeQuery();            //便利结果集            while (rs.next()) {                //获取content字段的数据                Reader reader = rs.getCharacterStream(2);                //创建文件输出流对象                FileWriter fw = new FileWriter("D://url2.txt");                //边度边写                char[] chs = new char[1024];                int len;                while ((len=reader.read(chs))!=-1) {                    fw.write(chs, 0, len);                    //刷新                    fw.flush();                }                //关流                fw.close();                reader.close();            }        }catch(Exception e){            e.printStackTrace();        }finally{            //释放资源            JDBCUtil.close(conn, stmt, null);        }    }    private static void write() {        Connection conn = null;        PreparedStatement stmt = null;        try{            conn  = JDBCUtil.getConn();            String sql = "insert into news values(?,?);";            stmt = conn.prepareStatement(sql);            //设之参数            stmt.setString(1, "郭德纲即将来西安开20周年的巡演");            stmt.setClob(2, new FileReader("D://url.txt"));            //发送参数,并执行sql             int count = stmt.executeUpdate();            System.out.println(count);        }catch(Exception e){            e.printStackTrace();        }finally{            //释放资源            JDBCUtil.close(conn, stmt, null);        }    }}

3、事物

package com.jdbc.d_transation;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.SQLException;import com.jdbc.util.JDBCUtil;public class TransationDemo {    public static void main(String[] args) {        Connection conn  =null;        PreparedStatement stmt = null;        //扣除张三账户余额2000元        String delSql = "update account set balance=balance-2000 where name='zhangsan';";        String addSql = "update account set balance=balance+2000 where name='lisi';";        try{            conn = JDBCUtil.getConn();            //开启事务            conn.setAutoCommit(false);//将自动提交设置为手动提交            stmt = conn.prepareStatement(delSql);            //执行sql语句            stmt.executeUpdate();            //int i = 1/0;//假设在这里抛出了一个异常            //下面给李四账户增加钱的操作还会执行吗?            stmt  =conn.prepareStatement(addSql);            stmt.executeUpdate();            //手动提交            conn.commit();            System.out.println("转账成功");         }catch(Exception e){            e.printStackTrace();            //回滚            try {                conn.rollback();            } catch (SQLException e1) {                // TODO Auto-generated catch block                e1.printStackTrace();            }        }finally{            //释放资源            JDBCUtil.close(conn, stmt, null);        }    }}
原创粉丝点击