事务的ACID(acid)属性
当一个连接对象被创建时,默认情况下是自动提交事务:每次执行一个 SQL 语句时,如果执行成功,就会向数据库自动提交,而不能回滚
为了让多个 SQL 语句作为一个事务执行:
1. 调用 Connection 对象的 setAutoCommit(false); 以取消自动提交事务
2.在所有的 SQL 语句都成功执行后,调用 commit(); 方法提交事务
3.在出现异常时,调用 rollback(); 方法回滚事务
4.若此时 Connection 没有被关闭, 则需要恢复其自动提交状态
使用数据库的事务,我们需要配合异常处理try
public void testJDBCTransaction() { Connection conn = null; try { // 1.获取数据库连接 conn = JDBCUtils.getConnection(); // 2.开启事务 conn.setAutoCommit(false); // 3.进行数据库操作 // 4.若没有异常,则提交事务 conn.commit(); } catch (Exception e) { e.printStackTrace(); // 5.若有异常,则回滚事务 try { conn.rollback(); } catch (SQLException e1) { e1.printStackTrace(); }} finally { JDBCUtils.close(null, null, conn); } }
使用COMMIT 和 ROLLBACK语句,我们可以:
提交或回滚前的数据状态
提交后的数据状态
说了这么多,还是使用代码来举例说明更加清晰(数据库连接的JDBCUtils类上一章写过了):
package com.company.jdbcDemo; import com.company.jdbcDemo.JDBCUtils; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; /* AA给CC转账1000 AA 2000 CC 2000 try{ 开启事务 AA -= 1000 System.out.println(1/0); CC += 1000 提交(一旦提交数据不能再回滚(撤销)) }catch(Exception e){ 事务回滚(撤销) } CREATE TABLE account( NAME VARCHAR(20), balance INT ) */ public class AccountDemo { public static void main(String[] args) throws SQLException { //1.获取数据库连接对象 Connection connection = JDBCUtils.getConnection(); PreparedStatement ps = null; try { //2.开启事物--禁止自动提交 connection.setAutoCommit(false); //------------------------------------------------------------------- //3.做具体的操作---执行sql语句 //预编译 String sql = "update account set balance=? where name=?"; ps = connection.prepareStatement(sql); //给占位符赋值 ps.setInt(1, 1000); ps.setString(2, "aa"); //执行sql ps.executeUpdate(); System.out.println(1 / 0); //给占位符赋值 ps.setInt(1, 3000); ps.setString(2, "cc"); //执行sql ps.executeUpdate(); //------------------------------------------------------------------- //4.事务提交 connection.commit(); }catch (Exception e){ e.printStackTrace(); //5.事务回滚 connection.rollback(); }finally { //6.允许自动提交 connection.setAutoCommit(true); //7.关闭资源----最后关闭资源 JDBCUtils.close(ps,connection); } } }
概述
前面我们的示例代码中,一直在调用我写的那个JDBCUtils类来完成数据库的连接,如果我们在别的工程中,就需要复制一下我的那个类,并且我写的那个也不是很严谨,我前面实现的数据库连接方式存在以下问题:
使用数据库连接池
阿里德鲁伊连接池技术首先分为两步:
1.加入jar包
例如:druid-1.1.10.jar
2.代码步骤
第一步:建立一个数据库连接池
第二步:设置连接池的参数
第三步:获取连接
使用德鲁伊连接数据库的方式一
//1、创建数据源(数据库连接池)对象 DruidDataSource ds =new DruidDataSource(); //2、设置参数 //(1)设置基本参数 ds.setDriverClassName("com.mysql.jdbc.Driver"); ds.setUrl("jdbc:mysql://localhost:3306/test"); ds.setUsername("root"); ds.setPassword("mysql123"); //3、获取连接 Connection conn = ds.getConnection(); //如果这里没有关闭,就相当于没有还 conn.close();
使用德鲁伊连接数据库的方式二
// 创建配置文件druid.properties url=jdbc:mysql://localhost:3306/0319db ?rewriteBatchedStatements=true username=root password=123456 driverClassName=com.mysql.jdbc.Driver 代码如下: Properties pro = new Properties(); pro.load(TestDruid2.class.getClassLoader().getResourceAsStream("druid.properties")); DataSource ds= DruidDataSourceFactory.createDataSource(pro); Connection conn = ds.getConnection();
这里注意了,德鲁伊配置文件中的key,必须跟我下面一样,否则连接不成功哦
// druid.properties内容 url=jdbc:mysql://localhost:3306/demo username=root password=123321 driverClassName=com.mysql.jdbc.Driver
我就直接上操作了,这里还是使用我前面实现的那个JDBCUtils类哈,偷个懒…
package com.company.jdbc2; import com.company.jdbc.JDBCUtils; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanHandler; import org.apache.commons.dbutils.handlers.BeanListHandler; import org.junit.Test; import java.sql.SQLException; import java.util.List; /* 通过使用DBUtils工具类实现增,删,改,查的操作 */ public class DBUtilsDemo { @Test public void test() throws SQLException { //1.创建操作对象 QueryRunner queryRunner = new QueryRunner(); //2.增,删,改是一个方法 /* update(Connection conn, String sql, Object param) conn : 连接对象 sql : sql语句 param : 给占位符赋值的内容 */ String sql = "insert into student(sid,sname,sage) values(?,?,?)"; //返回值 :有几条数据受到影响 int i = queryRunner.update(JDBCUtils.getConnection(), sql, 10, "kongkong", 18); System.out.println("有" + i + "条数据受到影响"); } @Test public void test2() throws SQLException { QueryRunner queryRunner = new QueryRunner(); /* query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params) conn : 连接对象 sql : sql语句 */ String sql = "select sid a,sname,sage from student where sid=?"; //注意:类中的属性名一定要和字段名相同。如果不相同则需要在sql语句中使用别名 // Student student = queryRunner.query(JDBCUtils.getConnection(), sql, // new BeanHandler<Student>(Student.class), 10); sql = "select sid a,sname,sage from student"; List<Student> list = queryRunner.query(JDBCUtils.getConnection(), sql, new BeanListHandler<Student>(Student.class)); for (Student s : list) { System.out.println(s); } } }
使用批处理
当我们需要对进行大批量的数据操作时,可以采用批处理技术,很简单,在url中添加批处理的参数
jdbc:mysql://localhost:3306/Demo?rewriteBatchedStatements=true
示例代码,(咳咳,依旧是我那个JDBCUtils实现连接的工具类…)
package com.company.jdbc3; import com.company.jdbc.JDBCUtils; import org.junit.Test; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; /* 批处理: */ public class BatchDemo { /* 使用批处理: 1.mysql驱动包的版本必须为5.1.3x 才支持批处理 2.在url连接中添加如下参数 jdbc:mysql://localhost:3306/Demo?rewriteBatchedStatements=true 3.使用一些API: //添加到批处理中 ps.addBatch(); //执行批处理 ps.executeBatch(); //清空批处理 ps.clearBatch(); */ @Test public void test2() throws SQLException { //1.获取数据库连接 Connection connection = JDBCUtils.getConnection(); //2.预编译 PreparedStatement ps = connection.prepareStatement( "insert into student(sid,sname,sage) values(?,?,?)"); //3.给占位符赋值 for (int i = 1; i <= 100000 ; i++) { ps.setInt(1,i); ps.setString(2,"aaa"+i); ps.setInt(3,i); //添加到批处理中 ps.addBatch(); if (i % 1000 == 0){ //执行sql ps.executeBatch();//执行批处理 //清空批处理 ps.clearBatch(); } } //4.关资源 JDBCUtils.close(ps,connection); } @Test public void test() throws SQLException { //1.获取数据库连接 Connection connection = JDBCUtils.getConnection(); //2.预编译 PreparedStatement ps = connection.prepareStatement( "insert into student(sid,sname,sage) values(?,?,?)"); //3.给占位符赋值 for (int i = 1; i <= 100000 ; i++) { ps.setInt(1,i); ps.setString(2,"aaa"+i); ps.setInt(3,i); //执行sql ps.executeUpdate(); } //4.关资源 JDBCUtils.close(ps,connection); } }
到此这篇关于JDBC的扩展知识点总结的文章就介绍到这了,更多相关JDBC知识点内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
免责声明:本站发布的内容(图片、视频和文字)以原创、来自互联网转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:ts@56dr.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
Copyright © 2009-2021 56dr.com. All Rights Reserved. 特网科技 版权所有 珠海市特网科技有限公司 粤ICP备16109289号
域名注册服务机构:阿里云计算有限公司(万网) 域名服务机构:烟台帝思普网络科技有限公司(DNSPod) CDN服务:阿里云计算有限公司 中国互联网举报中心 增值电信业务经营许可证B2