事务、连接池、DBUtils工具类

一、事务

1.事务概念

事务是指一组最小逻辑操作单元,里面有多个操作。组成事务的每一部分必须同时提交成功。如果有一个操作失败,整个操作就回滚。

2.事务ACID特性
  • 原子性(Atomicity)原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
  • 一致性(Consistency)事务必须使数据库从一个一致状态变换到另外一个一致性状态。
  • 隔离性(Isolation)事务的隔离性是指多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所打扰,多个并发事务之间要相互隔离。
  • 持久性(Durability)事务是指一个事务一旦被提交,它对数据库中的数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。
3.转账的一个小案例

默认情况下,Connection对象处于自动提交模式下,这意味着它在执行每个语句后都会自动提交更改。

connection.setAutoCommit(false);//设置成手动提交事务
connection.rollback();//回滚事务
connection.commit();//手动提交事务

    //我们把扣钱和加钱放到一个事务中,统一手动提交,如果遇到异常我们就回滚事务;没有遇到异常就正常提交
        Connection connection =null;
        PreparedStatement preparedStatement1 =null;
        PreparedStatement preparedStatement2 =null;
        try {
            //张三给李四转钱
            connection = JDBCUtils.getConnection();
            connection.setAutoCommit(false);//设置成手动提交事务
            //张三的账户要扣钱
            String sql1="update users set money=money-1000 where username='张三'";
            preparedStatement1 = connection.prepareStatement(sql1);
            preparedStatement1.execute();
            //李四的账户要加钱
            String sql2="update users set money=money+1000 where username='李四'";
            preparedStatement2 = connection.prepareStatement(sql2);
            preparedStatement2.execute();

        } catch (Exception e) {
            //转账途中,如果遇到异常就回滚事务
            try {
                connection.rollback();//回滚事务
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();
        } finally {
            try {
                connection.commit();//手动提交事务
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                //释放资源
                connection.close();
                preparedStatement1.close();
                preparedStatement2.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

4.事务的隔离级别

(1).不考虑隔离性会出现的读问题
脏读:在一个事务中读取到另一个事务没有提交的数据。
不可重复读:在一个事务中,两次查询的结果不一致(针对的update操作)。不可重复读是指在数据库访问中,一个事务范围内两次相同的查询却返回了不同的数据。
虚读:在一个事务中,两次查询的结果不一致(针对的insert操作),无法演示出来,MySql已经默认避免了。
(2).MySQL有四种隔离级别

隔离级别
read uncommitted读未提交上面三种问题都会出现
read committed读已提交可以避免脏读的发生 Oracle 默认界别
repeatable read可重复读可以避免脏读和不可重复读的发生 MySQL 默认级别
serializable串行化可以避免所有的问题

(3).开启事务

start transaction;

(4).设置数据库的隔离级别

set session transaction isolation level  read uncommitted;

(5).查看数据库的隔离级别

select @@tx_isolation;

(6).四种隔离级别的效率
read uncommitted>read committed>repeatable read>serializable
(7).四种隔离级别的安全性
read uncommitted<read committed<repeatable read<serializable
(8).开发中绝对不允许脏读发生.
mysql中默认级别:repeatable read
oracle中默认级别:read committed
(9).java中控制隔离级别

设置数据库的隔离级别
connection.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);

二、连接池

1.连接池:存放有一定数量的连接对象,以便重复利用这个连接对象
2.为什么会有连接池?
因为建立数据库连接是一件非常耗时,耗资源的行为,所以通过连接池预先同数据库建立一些连接,放在内存中,应用程序需要建立数据库连接时直接到连接池中申请一个就行,使用完毕后再归还到连接池中。
3.市面上常见数据库连接池产品:DBCP、C3P0、阿里德鲁伊

(一)DBCP(DataBase Connection Pool)数据库连接池

是Java数据库连接池的一种,由Apache开发,通过数据库连接池,可以让程序自动管理数据库连接的释放和断开。

1.先导入DBCP的两个jar包,当然数据驱动jar包不能少
2.开始编码
  1. 硬编码:所有的数据库参数,通过代码来设置
//创建连接池
        BasicDataSource bs = new BasicDataSource();
//配置信息
        bs.setDriverClassName("com.mysql.jdbc.Driver");
        bs.setUrl("jdbc:mysql://localhost:3306/mydb");
        bs.setUsername("root");
        bs.setPassword("101721");
        Connection connection = bs.getConnection();
  1. 采用配置文件的方式
//采用配置文件的方式,来使用DBCP
        Properties properties = new Properties();
        properties.load(new FileReader("src/dbcp.properties"));
        //创建一个工厂
        DataSource ds = new BasicDataSourceFactory().createDataSource(properties);
        Connection connection = ds.getConnection();
(二)C3P0(DataBase Connection Pool)数据库连接池

C3P0是一个开源的JDBC连接池;它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展;目前使用它的开源项目有Hibernate、Spring等。
C3P0与DBCP区别:DBCP没有自动回收空闲连接的功能,C3P0有自动回收空闲连接的功能

1.导入C3P0的一个jar包
2.开始编码
  1. 硬编码
ComboPooledDataSource ds = new ComboPooledDataSource();
        ds.setDriverClass("com.mysql.jdbc.Driver");
        ds.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
        ds.setUser("root");
        ds.setPassword("101721");
        Connection connection = ds.getConnection();
  1. 采用配置文件的方式
    采用配置文件的方式,来使用C3P0
    C3P0对配置文件有以下要求:
    (1).配置文件的名称是固定的c3p0.properties 或者 c3p0-config.xml
    (2).配置文件必须放在src目录下
ComboPooledDataSource ds = new ComboPooledDataSource();
Connection connection = ds.getConnection();
(三)Druid(DataBase Connection Pool)数据库连接池

DRUID是阿里巴巴开源平台上一个数据库连接池实现,它结合了C3P0、DBCP、PROXOOL等DB池的优点,同时加入了日志监控,可以很好的监控DB池连接和SQL的执行情况,可以说是针对监控而生的DB连接池。

1.导入Druid的一个jar包
2.开始编码
  1. 硬编码
DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/mydb");
        ds.setUsername("root");
        ds.setPassword("101721");
        DruidPooledConnection connection = ds.getConnection();
  1. 采用配置文件的方式
Properties properties = new Properties();
        properties.load(new FileReader("druid.properties"));
        //通过一个工厂类,创建一个数据源
        DataSource ds = new DruidDataSourceFactory().createDataSource(properties);
        Connection connection = ds.getConnection();

三、DBUtils

Commons DbUtils是Apache组织提供的一个对JDBC进行简单封装的开源工具类库,使用它能够简化JDBC应用程序的开发,同时也不会影响程序的性能。

1.使用步骤
1.导入jar包
2.创建一个queryRunner类
	(queryRunner作用:操作sql语句)
	构造方法:new QueryRunner(DataSource ds);
3.编写sql
4.执行sql

2.DML操作
		//Commons DbUtils是Apache组织提供的一个对JDBC进行简单封装的开源工具类库,
        //1.导入DBUtils的jar包
        //2.创建 QueryRunner对象
        Properties properties = new Properties();
        properties.load(new FileReader("src/druid.properties"));
        DataSource dataSource = new DruidDataSourceFactory().createDataSource(properties);
        QueryRunner queryRunner = new QueryRunner(dataSource);
//进行DML,返回值:你影响的行数
        int i = queryRunner.update("insert into user(username,password) values(?,?)", "杨大哥", "888");
        if(i>0){
            System.out.println("插入成功");
        }else{
            System.out.println("插入失败");
        }
3.DQL操作
//查询
        //参数2,将查询的结果封装起来
        //BeanListHandle把从数据库查出来的多条数据,封装到对象里面,在把对象放到集合里
        List<User> list = queryRunner.query("select * from user", new BeanListHandler<User>(User.class));
        System.out.println(list);

        //BeanHandle查询一条结果,把这个结果封装到对象里面
        User user = queryRunner.query("select * from user", new BeanHandler<User>(User.class));
        System.out.println(user);

        //MapHandle()把查询的结果封装到Map集合里面
        Map<String, Object> map = queryRunner.query("select * from user", new MapHandler());
        System.out.println(map);
        Object username = map.get("username");
        System.out.println(username);
        Object password = map.get("password");
        System.out.println(password);
        System.out.println(map.size());
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值