事务及Druid开源连接池知识点及案例

本文介绍了事务的概念及其管理API,包括如何开启、提交和回滚事务。接着讲解了连接池的重要性,特别是Druid和C3P0两个开源连接池的概述。此外,还探讨了DBUtils工具类的作用和使用,以及如何在不同场景下实现增删改查操作。通过示例代码展示了如何在JDBC中进行事务管理和连接池的实战应用。

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

第一部分:今日技术操作及其概述

注意:1.配置文件,如.properties 和今天的c3p0-config.xml在src下
2.如果是jar包,在项目下创建一个文件夹,复制在文件夹中
3.在用提供的第三方配置文件时,列如成c3p0-config.xml时,要记得点击c3p0-config.xml,把里面的数据库名称和密码改成自己的
4.增删改查构造方法的上面必须要加上@Test

1.事务的概念
*事务指的是逻辑上的一组操作,组成这组操作各个逻辑单元要么全都成功,要么全都失败。

2.事务管理API
*开启事务 conn.setAutoCommit(false); 【是否自动提交,为false】
*提交事务 conn.commit(); 【自动提交为false,我们手动提交】
*回滚事务 try { 【如果发生异常用回滚,在回滚中如果发生异常就try catch】
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}

3.什么是连接池
*连接池是创建和管理一个连接的缓冲池的技术,这些连接准备好被任何需要它们的线程使用
*补充: 连接池是装有连接的容器,使用连接的话,可以从连接池中进行获取,使用完成之后将连接归还给连接池。

4.为什么要学习连接池
*连接对象创建和销毁是需要耗费时间的,在服务器初始化的时候就初始化一些连接。把这些连接放入到内存中,
使用的时候可以从内存中获取,使用完成之后将连接放入连接池中。从内存中获取和归还的效率要远远高于创建和销毁的效率。(提升性能)。

5.Druid开源连接池的概述
*Druid是阿里旗下开源连接池产品,使用非常简单,可以与Spring框架进行快速整合。

在配置文件中可以写:
#<!-- 初始化连接 -->
initialSize=10

#最大连接数量
maxActive=50

#<!-- 最大空闲连接 -->
maxIdle=20

#<!-- 最小空闲连接 -->
minIdle=5

6.C3P0开源连接池的概述
*C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它们的开源项目有Hibernate,Spring等

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

8.为什么要学习DBUtils
*因为JDBC手写比较麻烦,而且有非常多的代码是类似的。比如获得连接,预编译SQL,释放资源等..那么可以将这些代码抽取出来放到工具类中。
将类似的代码进行抽取。大大简化JDBC的编程。

9.DBUtils的API概述
*QueryRunner对象 核心运行类

第二部分:代码实现==========

1.在转帐的代码中添加事务管理
[1]package JDBCaccount;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import org.junit.Test;

public class account {
@Test
public void demo(){
Connection conn = null;
PreparedStatement pst = null;
try{

        //完成数据库的连接
        conn = JDBC工具类.get();
        //开启事务
        conn.setAutoCommit(false);             【是否自动提交,为false】

        //获取执行者对象
        String sql = "update account set money=money+? where name=?";
        pst = conn.prepareStatement(sql);
        //给占位符设置参数
        //给aaa减1000元
        pst.setDouble(1, -1000);
        pst.setString(2, "aaa");
        pst.executeUpdate();

        int i = 1 / 0; --------------这里会出现异常,出现异常就不会向下执行,如果没有事务管理三步骤,那么账户的钱aaa会减1000,而bbb不会加1000,这是不可以的,
                                     如果此处有异常,就直接执行下面catch语句中回滚,转账就停止,之前被扣的钱就重新还给用户
        //给bbb加1000元             
        pst.setDouble(1, 1000);
        pst.setString(2, "bbb");
        pst.executeUpdate();
        //提交事务
        conn.commit();            【自动提交为false,我们手动提交】
    }catch(Exception e){
        // 回滚事务: 【如果发生异常用回滚,在回滚中如果发生异常就try catch】
        try {
            conn.rollback();
        } catch (SQLException e1) {
            e1.printStackTrace();
        }
        e.printStackTrace();
    }finally{
        JDBC工具类.method(conn, pst);
    }
}

}

[2] 配置文件
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/zhanghu?reWriteBacthedStatements=true
username=root
password=0000

2.C3P0开源连接池工具类和其增删改查
[1]C3P0工具类
package C3P0开源连接池练习;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class C3P0工具类 {
private C3P0工具类(){}
//创建C3P0数据连接池对象
private static ComboPooledDataSource dataSource = new ComboPooledDataSource();
//获取数据库连接+
·
public static Connection getConnection() throws Exception{
return dataSource.getConnection();

}
//释放资源
public static void method(Connection conn, Statement stmt, ResultSet rs){
    if(conn != null){
        try {
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        conn = null;
    }
    if(stmt != null){
        try {
            stmt.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        stmt = null;
    }
    if(rs != null){
        try {
            rs.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        rs = null;
    }
}
public static void method(Connection conn, Statement stmt){
    if(conn != null){
        try {
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        conn = null;
    }
    if(stmt != null){
        try {
            stmt.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        stmt = null;
    }
}

}

[2]C3P0增删改查
package C3P0开源连接池练习;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import org.junit.Test;

public class C3P0增删改查 {

//增加

@Test
public void insert(){
    Connection conn = null;
    PreparedStatement pst = null;
    try {
        //获取数据库连接对象
        conn=C3P0工具类.getConnection();
        //创建SQL语句,获取执行者对象
        String sql="insert into account values (null,?,?)"; 
        pst=conn.prepareStatement(sql);
        //对SQL语句中的占位符进行赋值
        pst.setString(1,"ddd");
        pst.setInt(2,15000);
        //执行SQL语句
        pst.executeUpdate();
    } catch (Exception e) {
        e.printStackTrace();
    }finally{
        C3P0工具类.method(conn, pst);
    }
}

//删除
@Test
public void del(){
    Connection conn = null;
    PreparedStatement pst = null;
    try {
        //创建数据库连接
        conn = C3P0工具类.getConnection();
        //创建执行者对象
        String sql = "delete from account where name=?";
        pst = conn.prepareStatement(sql);
        //给占位符赋值
        pst.setString(1, "ddd");
        //执行SQl语句
        pst.executeUpdate();
    } catch (Exception e) {
        e.printStackTrace();
    }finally{
        //释放资源
        C3P0工具类.method(conn, pst);
    }
}

//修改
@Test
public void update(){
    Connection conn = null;
    PreparedStatement pst = null;
    try {
        //创建数据库连接
        conn = C3P0工具类.getConnection();
        //创建执行者对象
        String sql = "update account set money=? where name=?";
        pst = conn.prepareStatement(sql);
        //给占位符进行赋值
        pst.setInt(1, 9500);
        pst.setString(2, "aaa");
        //执行sql语句
        pst.executeUpdate();
    } catch (Exception e) {
        e.printStackTrace();
    }finally{
        //释放资源
        C3P0工具类.method(conn, pst);
    }
}

//查询
@Test
public void select(){
    Connection conn = null;
    PreparedStatement pst = null;
    ResultSet rs = null;
    try {
        //创建数据库连接对象
        conn = C3P0工具类.getConnection();
        //创建sql语句和执行者对象
        String sql = "select*from account";
        pst = conn.prepareStatement(sql);
        //执行SQL语句
        rs=pst.executeQuery();
        //遍历打印
        while(rs.next()){
            System.out.println(rs.getInt("id")+"\t"+rs.getString("name")+"\t"+rs.getInt("money"));
        }
    } catch (Exception e) {
        e.printStackTrace();
    }finally{
        //释放资源
        C3P0工具类.method(conn, pst, rs);
    }
}

}

3.Druid开源连接池工具类和其增删改查

[1]Druid工具类

package Druid开源连接池练习;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import javax.sql.DataSource;

import com.alibaba.druid.pool.DruidDataSourceFactory;

public class Druid工具类 {
private Druid工具类(){}
private static DataSource dataSource;

static{
    try {
        //读取配置文件,创建properties集合
        Properties ppt = new Properties();
        InputStream is = Druid工具类.class.getClassLoader().getResourceAsStream("druid.properties");
        ppt.load(is);
        //创建数据库连接池对象
        dataSource=  DruidDataSourceFactory.createDataSource(ppt);           [DruidDataSourceFactory是一个类   createDataSource是一个方法 ,返回是一个对象]
    } catch (Exception e) {
        e.printStackTrace();
    }
}
//获取数据库连接
public static Connection getConnection() throws Exception{
    return dataSource.getConnection();
}
//释放资源
public static void method(Connection conn, Statement stat, ResultSet rs){
    if(conn != null){
        try {
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        conn = null;
    }
    if(stat != null){
        try {
            stat.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        stat = null;
    }
    if(rs != null){
        try {
            rs.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        rs = null;
    }
}
public static void method(Connection conn, Statement stat){
    if(conn != null){
        try {
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        conn = null;
    }
    if(stat != null){
        try {
            stat.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        stat = null;
    }
}

}

[2]Druid增删改查

package Druid开源连接池练习;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import org.junit.Test;

public class Druid增删改查 {
//增加
@Test
public void insert(){
Connection conn = null;
PreparedStatement pst = null;
try {
//创建数据库连接对象
conn = Druid工具类.getConnection();
//创建执行者对象
String sql = “insert into account values(4,?,?)”;
pst = conn.prepareStatement(sql);
//给占位符赋值
pst.setString(1, “fff”);
pst.setInt(2, 12500);
//执行sql语句
pst.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}finally{
//释放资源
Druid工具类.method(conn, pst);
}
}

//删除
@Test
public void del(){
    Connection conn = null;
    PreparedStatement pst = null;
    try {
        //创建数据库连接对象
        conn = Druid工具类.getConnection();
        //创建执行者对象
        String sql = "delete from account where name=?"; 
        pst = conn.prepareStatement(sql);
        //给占位符赋值
        pst.setString(1,"fff");
        //执行sql语句
        pst.executeUpdate();
    } catch (Exception e) {
        e.printStackTrace();
    }finally{
        //释放资源
        Druid工具类.method(conn, pst);
    }
}

//修改
@Test
public void update(){
    Connection conn = null;
    PreparedStatement pst = null;
    try {
        //创建数据库连接对象
        conn = Druid工具类.getConnection();
        //创建sql语句并创建执行者对象
        String sql= "update account set money=? where name=?";
        pst = conn.prepareStatement(sql);
        //给占位符赋值
        pst.setInt(1, 12345);
        pst.setString(2, "ccc");
        //执行sql语句
        pst.executeUpdate();
    } catch (Exception e) {
        e.printStackTrace();
    }finally{
        //释放资源
        Druid工具类.method(conn, pst);
    }
}

//查询
@Test
public void select(){
    Connection conn = null;
    PreparedStatement pst = null;
    ResultSet rs = null;
    try {
        //创建数据库连接对象
        conn = Druid工具类.getConnection();
        //创建执行者对象
        String sql = "select*from account";
        pst = conn.prepareStatement(sql);
        //执行sql语句
        rs = pst.executeQuery();
        //遍历
        while(rs.next()){
            System.out.println(rs.getInt("id")+"\t"+rs.getString("name")+"\t"+rs.getInt("money"));
        }
    } catch (Exception e) {
        e.printStackTrace();
    }finally{
        //释放资源
        Druid工具类.method(conn, pst, rs);
    }
}

}

4.DBUtils工具类和其增删改查

[1]工具类
package DB工具类练习;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.sql.DataSource;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class DB工具类 {
private DB工具类(){}
//创建C3P0数据库连接池对象
private static ComboPooledDataSource dataSource = new ComboPooledDataSource();
//获取数据库连接
public static Connection getConnection() throws Exception{
return dataSource.getConnection();
}
//获取数据库连接池对象
public static DataSource getDataSource(){
return dataSource;
}
//释放资源
public static void method(Connection conn, Statement stat){
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
if(stat != null){
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
}
stat = null;
}
}
public static void method(Connection conn, Statement stat,ResultSet rs){
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
if(stat != null){
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
}
stat = null;
}
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
}
}
}

[2]DBUtils增删改

package DB工具类练习;

import java.sql.SQLException;

import org.apache.commons.dbutils.QueryRunner;
import org.junit.Test;

public class DB增删改 {
//创建QueryRunner
QueryRunner qr = new QueryRunner(DB工具类.getDataSource());
//添加
@Test
public void insert(){
try {
//创建sql语句并赋值
qr.update(“insert into account values(null,?,?)”,”ddd”,16000);
} catch (SQLException e) {
e.printStackTrace();
}
}
//删除
@Test
public void delete(){
try {
//创建sql语句并赋值
qr.update(“delete from account where name=?”,”ccc”);
} catch (SQLException e) {
e.printStackTrace();
}
}
//修改
@Test
public void update(){
try {
//创建sql语句并赋值
qr.update(“update account set name=? where name=?”,”qqq”,”bbb”);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

5.DBUtils之C3P0数据库连接池的事务管理
[1] C3P0Utils(比C3P0工具类多一步)
package com.itheima.utils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.sql.DataSource;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class C3P0Utils {
private C3P0Utils(){}

//创建c3p0数据库连接池对象即可
private static ComboPooledDataSource dataSource = new ComboPooledDataSource();

//获取数据库连接
public static Connection getConnection() throws Exception{
    return dataSource.getConnection();
}

//获取数据库连接池对象
public static DataSource getDataSource(){
    return dataSource;
}

//释放资源
public static void release(Connection con,Statement stat,ResultSet rs){
    if(con != null) {
        try {
            con.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        con = null;
    }

    if(stat != null) {
        try {
            stat.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        stat = null;
    }

    if(rs != null) {
        try {
            rs.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        rs = null;
    }
}

public static void release(Connection con,Statement stat){
    if(con != null) {
        try {
            con.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        con = null;
    }

    if(stat != null) {
        try {
            stat.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        stat = null;
    }
}

}

[2]
package com.itheima.demo2;

import java.sql.Connection;

import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.junit.Test;

import com.itheima.utils.C3P0Utils;

/*
* C3P0数据库连接池的事务管理
*/
public class Demo02 {
@Test
public void update(){
QueryRunner qr = new QueryRunner();
Connection con = null;

    try{
        con = C3P0Utils.getConnection();
        //开启事务
        con.setAutoCommit(false);
        String sql = "UPDATE student SET sage = ? WHERE sname = ?";
        Object[] arr = {23,"张三"};
        qr.update(con, sql, arr);

        System.out.println(2 / 0);

        String sql2 = "UPDATE student SET sage = ? WHERE sname = ?";
        Object[] arr2 = {24,"李四"};
        qr.update(con, sql2, arr2);

        //提交事务、释放资源
        DbUtils.commitAndCloseQuietly(con);
    }catch(Exception e) {
        //回滚事物、释放资源
        DbUtils.rollbackAndCloseQuietly(con);
        e.printStackTrace();
    }
}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值