JDBC 其二(加强)批处理,大数据处理,事务

来源:互联网 发布:java图形界面放视频 编辑:程序博客网 时间:2024/05/16 17:30

JDBC进行批处理

1.使用批处理的原因: 

之前一次操作只能发送一条sql语句到数据库服务器,效率并不高。假如我们要发送2000条数据,那么必须发送2000条数据。 
所以现在可以使用sql缓存区,一次发送多条sql到数据库服务器执行,这种操作就叫做批处理。

2.JDBC批处理的API: 

(1)Statement批处理:

void addBatch(String sql)  //添加sql到缓存区(暂时不发送)int[] executeBatch() //执行批处理命令。 发送所有缓存区的sqlvoid clearBatch()  //清空sql缓存区
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

利用Statement进行批处理:

private static void testStatementBatch() {        Connection conn = null;        Statement stmt = null;        try{            conn = JDBCUtil.getConn();            stmt = conn.createStatement();            //每次给命令行中添加20条语句,一次性发送            for (int i = 1; i <= 2000; i++) {                String sql = "INSERT INTO student 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);        }    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

(2)PreparedStatement:

void addBatch() //添加参数到缓存区int[] executeBatch() //执行批处理命令。 发送所有缓存区的sqlvoid clearBatch()  //清空sql缓存区
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

利用Statement进行批处理:

private static void testPreparedStatementBatch() {        Connection conn = null;        PreparedStatement stmt =null;        try{            conn = JDBCUtil.getConn();            //创建一个动态sql语句            String sql = "INSERT INTO student VALUES(?,?);";            stmt = conn.prepareStatement(sql);            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);        }    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

JDBC获取自增长值






public class Demo {    @Test    public void test(){        //插入部门表数据        String deptSql = "INSERT INTO dept(deptName) VALUES(?)";        //插入员工表数据        String empSql = "INSERT INTO employee(empName,deptId) VALUES(?,?)";        Connection conn = null;        PreparedStatement stmt = null;        ResultSet rs = null;        try{            //获取连接            conn = JdbcUtil.getConnection();            /**             * 1)插入部门             */            //预编译部门sql            //stmt = conn.prepareStatement(deptSql);            //            /**             * 1.1 使用两个参数的prepareStatement()方法,指定可以返回自动增长的键值             * Statement.RETURN_GENERATED_KEYS: 可以返回自动增长值             * Statement.NO_GENERATED_KEYS: 不能返回自动增长值             */            stmt = conn.prepareStatement(deptSql, Statement.RETURN_GENERATED_KEYS);            //设置参数            stmt.setString(1, "秘书部");            //执行部门sql            stmt.executeUpdate();            /**             * 1.2 获取自增长的值             */            rs = stmt.getGeneratedKeys();            Integer deptId = null;            if(rs.next()){                deptId = rs.getInt(1);//得到第一行第一列的值            }            /**             * 2)插入员工,员工在刚添加的部门中             */            stmt = conn.prepareStatement(empSql);            //设置参数            stmt.setString(1, "李四");            stmt.setInt(2, deptId);  //如何获取刚刚添加的部门ID??            //执行员工sql            stmt.executeUpdate();        }catch(Exception e){            e.printStackTrace();        }finally{            JdbcUtil.close(conn, stmt, rs);        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

JDBC处理大容量的数据






1.大容量: 

(1)字符: 

存储字符内容:MySQL:char(0-255),varchar(0-65535)长度有限。 
大容量的字符字段: 
*MySQL:text(64k) longtext(4G字符内容) 
*Oracle:clob longclob 

(2)字节: 

*MySQL:blob(65KB) mediumbolb(16MB) longblob(4GB) 
*Oracle:blob 

2.JDBC操作字符文件

public class Demo {    /**     * 文件保存到数据中     */    @Test    public void testWrite(){        Connection conn = null;        PreparedStatement stmt = null;        try{            //获取连接            conn = JdbcUtil.getConnection();            //创建PreparedStatement            String sql = "INSERT INTO test1(content) VALUES(?)";            stmt =conn.prepareStatement(sql);            //设置参数            /**             * 参数一: 参数位置             * 参数二: 输入字符流             */            /**             * 读取本地文件,返回输入字符流             */            FileReader reader = new FileReader(new File("e:/Demo1.java"));            stmt.setClob(1, reader);            //执行sql            int count = stmt.executeUpdate();            System.out.println("影响了"+count+"行");        }catch(Exception e){            e.printStackTrace();        }finally{            JdbcUtil.close(conn, stmt, null);        }    }    /**     * 从数据中读取文本内容     */    @Test    public void testRead(){        Connection conn = null;        PreparedStatement stmt = null;        ResultSet rs = null;        try{            //获取连接            conn = JdbcUtil.getConnection();            String sql = "SELECT * FROM test1 where id=?";            stmt = conn.prepareStatement(sql);            //设置参数            stmt.setInt(1, 2);            //执行sql,返回结果集            rs = stmt.executeQuery();            if(rs.next()){                //方式一:当做字符串取出数据                /*                String content = rs.getString("content");                System.out.println(content);                */                //方式二:返回输入流形式                Clob clob = rs.getClob("content");                Reader reader = clob.getCharacterStream();                //写出到文件中                FileWriter writer = new FileWriter(new File("e:/Demo2.java"));                char[] buf = new char[1024];                int len = 0;                while( (len=reader.read(buf))!=-1){                    writer.write(buf, 0, len);                }                //关闭流                writer.close();                reader.close();            }        }catch(Exception e){            e.printStackTrace();        }finally{            JdbcUtil.close(conn, stmt, rs);        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82

3.JDBC操作字节文件

public class Demo {    /**     * 文件保存到数据库中     */    @Test    public void testWrite(){        Connection conn = null;        PreparedStatement stmt = null;        try{            //获取连接            conn = JdbcUtil.getConnection();            String sql = "insert into test2(content) values(?)";            stmt = conn.prepareStatement(sql);            //设置参数            /**             * 参数一:参数位置             * 参数二:输入字节流             */            /**             * 读取本地文件             */            InputStream in = new FileInputStream(new File("e:/abc.wmv"));            //stmt.setBlob(1, in);            stmt.setBinaryStream(1, in);            //执行            stmt.executeUpdate();        }catch(Exception e){            e.printStackTrace();        }finally{            JdbcUtil.close(conn, stmt, null);        }    }    /**     * 从数据中读取字节内容     */    @Test    public void testRead(){        Connection conn = null;        PreparedStatement stmt = null;        ResultSet rs = null;        try{            //获取连接            conn = JdbcUtil.getConnection();            String sql = "SELECT * FROM test2 where id=?";            //获取PreparedStatement            stmt = conn.prepareStatement(sql);            //设置参数            stmt.setInt(1, 1);            //执行sql            rs = stmt.executeQuery();            if(rs.next()){                //返回输入流                //InputStream in = rs.getBinaryStream("content");                InputStream in = rs.getBlob("content").getBinaryStream();                //写出文件中                FileOutputStream out = new FileOutputStream(new File("e://3.jpg"));                byte[] buf = new byte[1024];                int len = 0;                while((len=in.read(buf))!=-1){                    out.write(buf, 0, len);                }                //关闭流                out.close();                in.close();            }        }catch(Exception e){            e.printStackTrace();        }finally{            JdbcUtil.close(conn, stmt, rs);        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74

注意: MySQL数据库默认情况下,只能存储不超过1m的文件,由于max_allowed_packet变量的限制。 
解决 : 可以修改: %mysql%/my.ini文件, 修改或添加max_allowed_packet变量,然后重启mysql即可。



数据库的事务处理




1.定义

事务: 把多条sql语句看做一个事务,这个事务要么全部做,要么全部不做(要么一起成功,要么一起失败)。

2.MySQL事务操作命令: 

set autocommit =0 / 1; :设置是否自动提交事务 
1: 表示自动提交事务,每执行一条sql语句,自动提交事务。 
0: 表示关闭自动提交事务。 
commit; :提交事务,一旦提交事务不能回滚 
rollback;: 回滚事务。回滚到事务的起始点。

3.JDBC事务操作: 

Connection.setAutoCommit(false) : 开启事务 
Connection.commit(); : 成功执行,最后提交事务 
Connection.rollback(); : 一旦遇到错误,回滚事务

需求:模拟银行转账,weide问james借2000块钱。 
图解: 
这里写图片描述

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) {        //Weide问James借2000块钱        Connection conn = null;        PreparedStatement stmt = null;        String sql1 ="UPDATE account SET balance=balance-2000 WHERE name='李四';";        String sql2 ="UPDATE account SET balance=balance+2000 WHERE name='张三';";        try{            conn = JDBCUtil.getConn();            //开启事务,将自动提交改为手动提交            conn.setAutoCommit(false);            stmt = conn.prepareStatement(sql1);            stmt.executeUpdate();            //假设出现异常            //int i =10/0;            stmt = conn .prepareStatement(sql2);            stmt.executeUpdate();            //提交事务            conn.commit();        }catch(Exception e){            try {                conn.rollback();            } catch (SQLException e1) {                // TODO Auto-generated catch block                e1.printStackTrace();            }            e.printStackTrace();        }finally{            JDBCUtil.close(conn,stmt,null);        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

分析:假设张JamesWeide账户里本来都是5000块钱,WeideJames借2000块钱,则应该James账户减2000,Weide账户增加2000,然而如果转账事务执行过程中出现异常,例如:int i =10/0;这个运行时期异常,James账户此时已经减了2000块钱,而Weide账户还没有增加2000块钱,出现了异常,所以回滚到事务开始的地方,两人账户都还是5000块钱。 
如果没有出现什么异常,事务顺利执行,则银行转账操作执行成功,James账户减2000,Weide账户增加2000。

4.事务4大特性: 

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

阅读全文
0 0
原创粉丝点击