数据库连接池(Connection pooling)是程序启动时建立足够的数据库连接,并将这些连接组成一个连接池,由程序动态地对池中的连接进行申请,使用,释放
为何使用数据库连接池?
-
数据库连接是一件费时的操作,连接池可以使多个操作共享一个连接
-
数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。可以通过设定连接池最大连接数来防止系统无尽的与数据库连接。
-
使用连接池是为了提高对数据库连接资源的管理,数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个。
数据库连接池的运行机制
(1) 程序初始化时创建连接池
(2) 使用时向连接池申请可用连接
(3) 使用完毕,将连接返还给连接池
(4) 程序退出时,断开所有连接,并释放资源
常见连接池种类:
-
DBCP连接池
-
c3p0连接池
-
druid连接池(主要介绍)
druid连接池的使用
使用步骤:
1.导入jar包: druid-xxx.jar、mysql-connector-java-5.1.47.jar
2.定义配置文件:可以命名为druid.properties
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/java2216?useSSL=false
username=root
password=***
3.加载配置文件druid.properties
4.获取连接池对象
5.获取数据库连接
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class DruidUtil {
private static DataSource dataSource;
private DruidUtil(){}
static {
//创建properties 对象解析 properties文件
Properties properties = new Properties();
//获取类加载器 读取根路径下的资源文件
ClassLoader classLoader = DruidUtil.class.getClassLoader();
InputStream resourceAsStream = classLoader.getResourceAsStream("jdbc.properties");
try {
properties.load(resourceAsStream);
// 实例化一个数据库连接池
dataSource = DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
//获取数据库连接池的方法
public static DataSource getDataSource(){
return dataSource;
}
//获取数据库的连接
public static Connection getConnection(){
Connection connection = null;
try {
connection = dataSource.getConnection();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return connection;
}
//释放资源
public static void closeAll(Connection connection, Statement statement, ResultSet resultSet){
if(resultSet!=null){
try {
resultSet.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(statement!=null){
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(connection!=null){
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
DBUtils工具的使用
如果只使用JDBC进行开发,会发现冗余代码过多,为了简化JDBC开发,采用apache commons组件一个成员:DBUtils。DBUtils是java编程中的数据库操作实用工具,小巧简单实用,DBUtils封装了对JDBC的操作,简化了JDBC操作,可以少写代码。 Dbutils三个核心功能介绍:
-
QueryRunner中提供对sql语句操作的API.
-
ResultSetHandler接口,用于定义select操作后,怎样封装结果集.
-
DbUtils类,它就是一个工具类,定义了关闭资源与事务处理的方法
QueryRunner核心类:
-
QueryRunner(DataSource ds) ;传入参数为连接池
-
update(String sql, Object… params) ,执行insert update delete操作
-
query(String sql, ResultSetHandler rsh, Object… params) ,执行 select操作
动态sql的实现:根据用户传递的参数进行查询
import cn.kgc.jdbc.entity.User;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class TestSQL {
public static void main(String[] args) {
String sql = " select * from user where '1'='1' ";
String username = "lucy";
String tel = "88888";
//创建集合保存参数
ArrayList<Object> params = new ArrayList<>();
if (username!=null){
sql+=" and username = ?";
params.add(username);
}
if(tel!=null){
sql+=" and tel = ?";
params.add(tel);
}
System.out.println(sql);
System.out.println(params);
QueryRunner queryRunner = new QueryRunner(DruidUtil.getDataSource());
try {
List<User> users = queryRunner.query(sql, new BeanListHandler<User>(User.class),params.toArray());
System.out.println("users = " + users);
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
JDBC事务演示
import cn.kgc.jdbc.util.DruidUtil;
import org.apache.commons.dbutils.QueryRunner;
import java.sql.Connection;
import java.sql.SQLException;
/**
* 演示jdbc数据操作时的事务处理
* 转账业务
* 事务: 完成一次业务操作需要执行的sql语句,sql语句要么全部成功要么全部失败
*
* jdbc的事务默认自动提交
*/
public class TestTransaction {
public static void main(String[] args) {
QueryRunner queryRunner = new QueryRunner();
// 通过连接 手动控制事务
Connection connection = DruidUtil.getConnection();
try {
connection.setAutoCommit(false);
// 1001 -> 1002 100
String sql ="update account set money = money + ? where account = ?";
int update = queryRunner.update(connection,sql, -100, "1001");
System.out.println(update);
int i = 1/0;
update = queryRunner.update(connection,sql, 100, "1002");
System.out.println("update = " + update);
// 以上两条sql语句全部执行成功 手动提交事务
connection.commit();
} catch (Exception throwables) {
System.out.println("被抓取异常");
try {
//设置事务的回滚
connection.rollback();
} catch (SQLException e) {
e.printStackTrace();
}
throwables.printStackTrace();
}
}
}