Transaction事件+数据库连接池dbcp&cpds&DBUtils

本文详细介绍了事务的概念及其四大特性,包括原子性、一致性、隔离性和持久性,并深入探讨了数据库连接池的作用及其实现方式,包括DBCP和C3P0等流行工具。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

事务[Transaction,简称tx]

事务指逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部失败。即不存在一半成功,一半失败的情况。

事务的四大特性

原子性(Atomicity):事务中所有操作是不可再分割的原子单位,
事务中所有操作要么全部执行成功,要么全部执行失败。
一致性(Consistency):事务执行后,数据库状态与其它业务规则保持一致,
如转账业务,无论事务执行成功与否,参与转账的两个账号余额之和应该是不变的。
隔离性(Isolation):隔离性是指在并发操作中,不同事务之间应该隔离开来,
使每个并发中的事务不会相互干扰。
持久性(Durability):一旦事务提交成功,事务中所有的数据操作都必须被持久化到数据库中,即使提交事务后,数据库马上崩溃,在数据库重启时,也必须能保证通过某种机制恢复数据

事务常用的API

01——setAutoCommit(boolean):设置是否为自动提交事务,如果true(默认值)表示自动提交,也就是每条执行的SQL语句都是一个单独的事务,如果设置false,那么就相当于开启了事务了。
02——commit():提交结束事务。
03——rollback():回滚结束事务。

数据库连接池,简称“池”
用池来管理Connection,这可以重复使用Connection。有了池,所以我们就不用自己来创建Connection,而是通过池来获取Connection对象。当使用完Connection后,调用Connection的close()方法也不会真的关闭Connection,而是把Connection“归还”给池。池就可以再利用这个Connection对象了。这个池要等到Web服务器停止,或应用程序彻底结束时,才会直正销毁。池销毁之前,池会让池中每个Connection对象调用close()方法来关闭自己。

原SUN公司为数据库连接池提供了公共的接口:叫javax.sql.DataSource,各个厂商可以让自己的连接池实现这个接口
市场上流行的JDBC数据库连接池实现

01——DBCP(早期)
DBCP是Apache提供的一款开源免费的数据库连接池!
Hibernate3.0之后不再对DBCP提供支持!
实现类:BasicDataSource
准备工作:
导入commons-collections.jar
commons-dbcp-1.3.jar
commons-pool.jar
mysql-connector-java-5.1.7-bin.jar到/WEB-INF/lib/目录下

/**
 * DBCP数据库连接池的使用
 */
public class Demo01 {
    private static BasicDataSource basicDataSource = new BasicDataSource();
    static{
        //设置数据库连接池基本属性
basicDataSource.setDriverClassName("com.mysql.jdbc.Driver");    basicDataSource.setUrl("jdbc:mysql://127.0.0.1:3306/jdbc");
        basicDataSource.setUsername("root");
        basicDataSource.setPassword("root");
        //设置数据库连接池扩展属性
        basicDataSource.setInitialSize(10);
        basicDataSource.setMaxActive(10);
        basicDataSource.setMaxIdle(5);
    }
    /**
     * 获取数据库连接
     */
    public Connection getConnection() throws SQLException{
        try {
            return basicDataSource.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
            throw e;
        }
    }
    /**
     * 主函数
     */
    public static void main(String[] args) throws Exception{
        Demo01 test = new Demo01();
        Connection conn = test.getConnection();
        System.out.println(basicDataSource.getNumIdle());
        if(conn!=null){
            System.out.println("已获取连接");
            conn.close();
            System.out.println(basicDataSource.getNumIdle());
        }else{
            System.out.println("未获取连接");
        }
    }
}

02——C3P0(如今)
C3P0也是开源免费的连接池!C3P0被很多人看好!
实现类:ComboPooledDataSource
准备工作:
导入 c3p0-0.9.1.2.jar
mysql-connector-java-5.1.7-bin.jar到/WEB-INF/lib/目录下

* C3P0数据库连接池的使用方式一
 */
public class Demo01 {
    private static ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
    static{
        try {
            //设置数据库连接池基本属性      comboPooledDataSource.setDriverClass("com.mysql.jdbc.Driver");      comboPooledDataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/jdbc");
            comboPooledDataSource.setUser("root");
            comboPooledDataSource.setPassword("root");
            //设置数据库连接池扩展属性
            comboPooledDataSource.setInitialPoolSize(10);
            comboPooledDataSource.setMaxPoolSize(10);
            comboPooledDataSource.setAcquireIncrement(5);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 获取数据库连接
     */
    public Connection getConnection() throws SQLException{
        try {
            return comboPooledDataSource.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
            throw e;
        }
    }
    /**
     * 主函数
     */
    public static void main(String[] args) throws Exception{
        Demo01 test = new Demo01();
        Connection conn = test.getConnection();
        if(conn!=null){
            System.out.println("已获取连接");
            conn.close();
        }else{
            System.out.println("未获取连接");
        }
    }
}

c3p0也可以指定配置文件,而且配置文件可以是properties,也可以是xml的。当然xml的高级一些了。但是c3p0的配置文件名必须为c3p0-config.xml,并且必须放在src路径下。

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
    <!-- 连接MySQL数据库服务器 -->
    <default-config>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/jdbc</property>
        <property name="user">root</property>
        <property name="password">root</property>
        <property name="initialPoolSize">50</property>
        <property name="maxPoolSize">100</property>
        <property name="acquireIncrement">10</property>
    </default-config>
    <!-- 连接Oracle数据库服务器-->
    <named-config name="oracle-config">
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/newsdb</property>
        <property name="user">root</property>
        <property name="password">roott</property>
        <property name="initialPoolSize">10</property>
        <property name="maxPoolSize">100</property>
        <property name="acquireIncrement">5</property>
    </named-config>
</c3p0-config>

/**
 * C3P0数据库连接池的使用方式二
 * 准备工作:
 * 1_编写c3p0-config.xml
 * 2_将c3p0-config.xml放在src目录下
 */
public class Demo03 {
    /**
     * 自动加载/src/c3p0-config.xml文件
     */
    private static ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource("oracle-config");
    /**
     * 获取数据库连接
     */
    public Connection getConnection() throws SQLException{
        try {
            return comboPooledDataSource.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
            throw e;
        }
    }
    /**
     * 主函数
     */
    public static void main(String[] args) throws Exception{
        Demo03 test = new Demo03();
        Connection conn = test.getConnection();
        if(conn!=null){
            System.out.println("已获取连接");
            conn.close();
        }else{
            System.out.println("未获取连接");
        }
    }
}


/**
 * C3P0数据库连接池的使用方式二B
 * 准备工作:
 * 1_编写c3p0-config.xml
 * 2_将c3p0-config.xml放在src目录下
 */
public class Demo03 {
    /**
     * 自动加载/src/c3p0-config.xml文件
     */
    private static ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource("oracle-config");
    /**
     * 获取数据库连接
     */
    public Connection getConnection() throws SQLException{
        try {
            return comboPooledDataSource.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
            throw e;
        }
    }
    /**
     * 主函数
     */
    public static void main(String[] args) throws Exception{
        Demo03 test = new Demo03();
        Connection conn = test.getConnection();
        if(conn!=null){
            System.out.println("已获取连接");
            conn.close();
        }else{
            System.out.println("未获取连接");
        }
    }
}
DBUtils工具类

DBUtils是Apache Commons组件中的一员,开源免费。
DBUtils是对JDBC的简单封装,但是它还是被很多个人和公司使用。
DBUtils工具类,需要导入dbutils.jar到项目的classpath中。即/WEB-INF/lib/目录下

01— 辅助类DBUtils类
02— 主要类QueryRunner(DataSource)类
update():执行insert、update、delete;
batch():相同结构的SQL,批处理

/**
 * 演示DBUtils工具类的CUD操作
 */
public class Demo01 {
    public void add() throws Exception{
        QueryRunner runner = new QueryRunner(JdbcUtil2.getDs());
        String sql = "insert into users(username,password,gender,city) values(?,?,?,?)";
        Object[] params = {"赵君","123456","男","深圳"};
        runner.update(sql,params);
    }
    public void addAll() throws Exception{
        QueryRunner runner = new QueryRunner(JdbcUtil2.getDs());
        String sql = "insert into users(username,password,gender,city) values(?,?,?,?)";
        Object[][] params = 
            {
                {"哈哈","123456","男","北京"},
                {"呵呵","123457","男","深圳"},
                {"嘻嘻","123458","男","上海"},
                {"嘿嘿","123459","男","广州"},
            };
        runner.batch(sql,params);
    }
    public void update() throws Exception{
        QueryRunner runner = new QueryRunner(JdbcUtil2.getDs());
        String sql = "update users set city=? where username=?";
        Object[] params = {"广州","赵君"};
        runner.update(sql,params);
    }
    public void delete() throws Exception{
        QueryRunner runner = new QueryRunner(JdbcUtil2.getDs());
        String sql = "delete from users where username=?";
        Object[] params = {"赵君"};
        runner.update(sql,params);
    }
    /**
     * 主函数
     */
    public static void main(String[] args) throws Exception{
        Demo01 test = new Demo01();
        //test.add();
        //test.update();
        //test.delete();
        test.addAll();
    }
}

DBUtils提供了很多个ResultSetHandler接口的实现,这些实现已经基本够用了。
01——MapHandler:单行处理器
把结果集转换成Map<String,Object>,其中key为列名,value为列值
02——MapListHandler:多行处理器
把结果集转换成List<Map<String,Object>>
03——BeanHandler:单行处理器
把结果集转换成Bean,该处理器需要Class参数,即Bean的类型
04——BeanListHandler:多行处理器
把结果集转换成List<Bean>
05——ScalarHandler:单行单列处理器
把结果集转换成Object。一般用于聚集查询
例如select count(id) from users


/**
 * 演示DBUtils工具类的R操作
 */
public class Demo {
    public void findByIdWithMapHandler() throws Exception{
        QueryRunner runner = new QueryRunner(JdbcUtil2.getDs());
        String sql = "select * from users";
        Map<String,Object> map = runner.query(sql,new MapHandler());
        System.out.println(map.get("username")+"#"+map.get("gender"));
    }
    public void findAllWithMapListHandler() throws Exception{
        QueryRunner runner = new QueryRunner(JdbcUtil2.getDs());
        String sql = "select * from users";
        List<Map<String,Object>> list = runner.query(sql,new MapListHandler());
        for(Map<String,Object> map : list){
            System.out.println(map.get("username")+"#"+map.get("gender"));
        }
    }
    public void findByIdWithBeanHandler() throws Exception{
        QueryRunner runner = new QueryRunner(JdbcUtil2.getDs());
        String sql = "select id,username,password,gender,city from users";
        User user = runner.query(sql,new BeanHandler<User>(User.class));        System.out.println(user.getUsername()+"#"+user.getGender());
    }
    public void findByIdWithBeanListHandler() throws Exception{
        QueryRunner runner = new QueryRunner(JdbcUtil2.getDs());
        String sql = "select * from users";
        List<User> userList = runner.query(sql,new BeanListHandler<User>(User.class));
        for(User user:userList){
            System.out.println(user.getUsername()+"#"+user.getGender());
        }
    }
    public void getTotalWithScalarHandler() throws Exception{
        QueryRunner runner = new QueryRunner(JdbcUtil2.getDs());
        String sql = "select count(id) from users";
        Long temp = (Long) runner.query(sql,new ScalarHandler());
        System.out.println(temp.intValue());
    }
    /**
     * 主函数
     */
    public static void main(String[] args) throws Exception{
        Demo02 test = new Demo02();
        //test.findByIdWithMapHandler();
        //test.findAllWithMapListHandler();
        //test.findByIdWithBeanHandler();
        //test.findByIdWithBeanListHandler();
        test.getTotalWithScalarHandler();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值