首页 > 学院 > 开发设计 > 正文

java学习笔记—JDBC4(19)

2019-11-14 23:34:44
字体:
来源:转载
供稿:网友
java学习笔记—JDBC4(19)

16 数据库事务

16.1 银行存款

#账户基本信息表 create table account (    accountid   varchar(18) ,  #账号    balance     double(10,2)   #余额 )#存款表 create table inaccount(    accountid   varchar(18) ,  #账号     inbalance     double(10,2) #存入余额 )向账户中存入100元:       Insert into inaccount(accountid, inbalance) values(‘500612345’,100);       Insert into account(accountid, balance) values(‘500612345’,100);

l 在数据库中,所谓事务是指作为单个逻辑工作单元执行的一系列操作 。

l 为确保数据库中数据的一致性,数据的操纵应当是离散的成组的逻辑单元:当它全部完成时,数据的一致性可以保持,而当这个单元中的一部分操作失败,整个事务应全部视为错误,所有从起始点以后的操作应全部回退到开始状态。

事务的操作:先定义开始一个事务,然后对数据作修改操作,这时如果提交(COMMIT),这些修改就永久地保存下来,如果回退(ROLLBACK),数据库管理系统将放弃您所作的所有修改而回到开始事务时的状态

l 事务的ACID属性

  • 1. 原子性(Atomicity)原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
  • 2. 一致性(Consistency)事务必须使数据库从一个一致性状态变换到另外一个一致性状态。(数据不被破坏)
  • 3. 隔离性(Isolation)事务的隔离性是指一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
  • 4. 持久性(Durability)持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来的其他操作和数据库故障不应该对其有任何影响

16.2JDBC 事务处理

l 事务处理:保证所有事务都作为一个工作单元来执行,即使出现了故障,都不能改变这种执行方式。当在一个事务中执行多个操作时,要么所有的事务都被提交(commit),要么整个事务回滚(rollback)到最初状态

l 在JDBC中,事务默认是自动提交的,每次执行一个SQL 语句时,如果执行成功,就会向数据库自动提交,而不能回滚

l 为了让多个 SQL 语句作为一个事务执行:

  • 调用 Connection 对象的 setAutoCommit(false); 以取消自动提交事务
  • 在所有的 SQL 语句都成功执行后,调用 commit(); 方法提交事务
  • 在出现异常时,调用 rollback(); 方法回滚事务

l 可以通过Connection的getAutoCommit()方法来获得当前事务的提交方式

16.3 事务处理:命令行实现

1 查看提交模式

select @@autocommit;

2 用begin,rollback,commit来实现 begin //开始一个事务

rollback //事务回滚

commit //提交事务

例如:

MySQL> begin;

mysql> insert into test values(9,'dd','dd');

mysql> commit;

3 直接用set来改变mysql的自动提交模式

MYSQL默认是自动提交的,也就是你提交一个QUERY,它就直接执行 set autocommit =0 禁止自动提交 set autocommit =1 开启自动提交, 来实现事务的处理。 *当你用 setautocommit =0 的时候,你以后所有的SQL都将做为事务处理,直

到你用commit确认或rollback结束。

* 注意:当你结束这个事务的同时也开启了个新的事务

16.4理解事务隔离级别

l 事务隔离级别(transaction isolationlevels):隔离级别就是对事务并发控制的四个等级。分为

1 串行化(SERIALIZABLE)

2 可重复读(REPEATABLE READ)

3 读已提交(READ COMMITED)

4 读未提交(READ UNCOMMITED)

17 批量处理---提高处理速度

l 当需要成批插入或者更新记录时。可以采用Java的批量更新机制,这一机制允许多条语句一次性提交给数据库批量处理。通常情况下比单独提交处理更有效率

l JDBC的批量处理语句包括下面两个方法:

  • addBatch(String):添加需要批量处理的SQL语句或是参数;
  • executeBatch();执行批量处理语句;

l 通常我们会遇到两种批量执行SQL语句的情况:

  • 多条SQL语句的批量处理;
  • 一个SQL语句的批量传参;

测试:

/** * 测试批量保存  *  statement *      PReparedStatement*//**     * 用Statement批量保存5000条记录     * mysql statement batch time=3047  //时间为3047 毫秒     */    @Test    public void testStatementBatch() {        Connection conn = null;        Statement stmt = null;        long time = System.currentTimeMillis();  //记录开始时间        conn = JDBCUtils.getConnection();        try {            stmt = conn.createStatement();            for(int i=0;i<5000;i++) {                String sql = "INSERT INTO b_user(id,NAME,PASSWord,age) VALUES(1,'t','t',1)";                stmt.addBatch(sql);   //批量插入            }            stmt.executeBatch();   // 执行批量处理语句            System.out.println("mysql statement batch time="+(System.currentTimeMillis()-time));        } catch (SQLException e) {            e.printStackTrace();        } finally {            JDBCUtils.closeResource(conn, stmt, null);        }    }

PreparedStatement:

/**     * 用PreparedStatement批量保存5000条记录     * mysql preparedstatement batch time=3094     */    @Test    public void testPreparedStatementBatch() {        Connection conn = null;        PreparedStatement pstmt = null;        long time = System.currentTimeMillis();        conn = JDBCUtils.getConnection();        String sql = "INSERT INTO b_user(id,NAME,PASSWORD,age) VALUES(?,?,?,?)";        try {            pstmt = conn.prepareStatement(sql);            for(int i=0;i<5000;i++) {                pstmt.setInt(1, 1);                pstmt.setString(2, "t");                pstmt.setString(3, "t");                pstmt.setInt(4, 1);                pstmt.addBatch();            }            pstmt.executeBatch();            System.out.println("mysql preparedstatement batch time="+(System.currentTimeMillis()-time));        } catch (SQLException e) {            e.printStackTrace();        } finally {            JDBCUtils.closeResource(conn, pstmt, null);        }}

18. MySQL BLOB 类型介绍

l MySQL中,BLOB是一个二进制大型对象,是一个可以存储大量数据的容器,它能容纳不同大小的数据。BLOB类型实际是个类型系列( TinyBlob、Blob、MediumBlob和LongBlob ),除了在存储的最大信息量上不同外,他们是等同的。

l MySQL的四种BLOB类型

l 实际使用中根据需要存入的数据大小定义不同的BLOB类型。需要注意的是:如果你存储的文件过大,数据库的性能会下降很多。

l 有4种TEXT类型:TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT。这些对应4种BLOB类型,有相同的最大长度和存储需求

例子:

/**     * 保存带图片的数据     */    @Test    public void saveImage() {        Connection conn = null;        PreparedStatement pstmt = null;        conn = JDBCUtils.getConnection();        String sql = "INSERT INTO bt_user (NAME,headimage) VALUES(?,?)";        try {            pstmt = conn.prepareStatement(sql);            pstmt.setString(1, "tom");            InputStream inputStream = new FileInputStream("D://............mm.jpg");            pstmt.setBinaryStream(2, inputStream,inputStream.available());            //mysql实现了所有方法,但有些方法执行无法通过,没有真正的实现            pstmt.executeUpdate();        } catch (SQLException e) {            e.printStackTrace();        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }    }

/**     * 读取数据库带图片的一条记录     */    @Test    public void getImage() {        Connection conn = null;        Statement stmt = null;        ResultSet rs = null;                conn = JDBCUtils.getConnection();        try {            stmt = conn.createStatement();            String sql = "select * from bt_user where id=1";            rs = stmt.executeQuery(sql);            if(rs.next()) {                Blob blob = rs.getBlob("headimage");                InputStream is = blob.getBinaryStream();                String path = "D://work//Workspaces//day14_jdbc//src//cn//itcast//mysql//bt//mm2.jpg";                OutputStream os = new FileOutputStream(path);                byte[] buffer = new byte[1024];                int len = -1;                while((len=is.read(buffer))!=-1) {                    os.write(buffer, 0, len);                }                //os.flush();                os.close();//close中有flush                is.close();            }        } catch (SQLException e) {            e.printStackTrace();        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        } finally {            JDBCUtils.closeResource(conn, stmt, rs);        }    }


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表