数据库连接池
概念
数据库连接池负责分配、管理和释放数据库连接,它允许应⽤程序重复使⽤⼀个现有的数据库连
接,⽽不是再重新建⽴⼀个;释放空闲时间超过最⼤空闲时间的数据库连接来避免因为没有释放
数据库连接⽽引起的数据库连接遗漏。这项技术能明显提⾼对数据库操作的性能。
简单来说,其实就是⼀个容器(集合),存放数据库连接的容器。
当系统初始化好后,容器被创建,容器中会申请⼀些连接对象,当⽤户来访问数据库时,从容器
中获取连接对象,⽤户访问完之后,会将连接对象归还给容器。
好处
- 节约资源
- ⽤户访问⾼效
连接池中连接的释放与使⽤原则
应⽤启动时,创建初始化数量的连接
当申请时⽆连接可⽤或者达到指定的最⼩连接数,按增量参数值创建新的连接
为确保连接池中最⼩的连接数的策略:
动态检查:定时检查连接池,⼀旦发现数量⼩于最⼩连接数,则补充对应的新连接,保证连接池正常运转
静态检查:空闲连接不⾜时,系统才检测是否达到最⼩连接数
按需分配,⽤过归还,空闲超时释放,获取超时报错
连接池也只是接⼝,具体实现由数据库⼚商来完成。常⻅连接池技术:
- C3P0:⼀个开源的 JDBC 连接池,它实现了数据源和 JNDI 绑定。⽬前使⽤它的开源项⽬有
Hibernate、Spring等。 - Druid:由阿⾥巴巴提供的数据库连接池实现技术,⽀持所有 JDBC 兼容的数据库,包括
Oracle、MySql等。 - DBCP:也是⼀个开源的连接池,是Apache Common成员之⼀,也是tomcat内置的连接
池。
C3P0连接池
使用步骤:
1、导入两个jar包c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar
不要忘记导入数据库驱动jar包。
2、定义配置文件:
名称: c3p0.properties 或者 c3p0-config.xml
路径:直接将文件放在src目录下即可。
3、创建核心对象,数据库连接池对象 ComboPooledDataSource
4、获取连接: getConnection
5、获取执行sql对象:Statement
6、定义sql并执行操作
public class Demo04NamedConfig {
public static void main(String[] args) throws SQLException {
// 1.配置文件 c3p0-config.xml,放到src下
// 2.创建对象 - 有参构造器(实际使用的是default - config选项)
ComboPooledDataSource dataSource = new ComboPooledDataSource("otherc3p0");
// 3.获得连接
Connection conn = dataSource.getConnection();
// 4.后续操作
System.out.println(conn);
// 5.归还连接 - conn为null
conn.close();
System.out.println(conn);
// 原始JDBC连接关闭情况
Connection connection = JDBCUtils.getConnection();
System.out.println(connection);
}
}
工具类
public class C3P0Utils {
private static ComboPooledDataSource dataSource = new ComboPooledDataSource();
public static ComboPooledDataSource getDataSource(){
return dataSource;
}
public static Connection getConnection(){
try {
return dataSource.getConnection();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return null;
}
}
Druid 连接池
使用步骤:
-
导⼊jar包:druid-1.1.16.jar
-
定义配置⽂件
配置⽂件名称:任意名称.properties
配置⽂件位置:src下的任意位置
配置⽂件内容:driverClassName=com.mysql.cj.jdbc.Driver url=jdbc:mysql://127.0.0.1:3306/java2106 username=root password=123wang456 initialSize=5 maxActive=10 maxWait=3000
-
加载配置⽂件。Properties
Properties pros = new Properties(); try { pros.load(DruidUtils.class.getResourceAsStream("druid.properties")); } catch (IOException e) { e.printStackTrace(); }
-
获取数据库连接池对象:通过⼯⼚来来获取DruidDataSourceFactory
DataSource ds = DruidDataSourceFactory.createDataSource(pros);
-
获取连接:getConnection
Connection conn = ds.getConnection();
public class Demo {
public static void main(String[] args) throws Exception {
Properties prop = new Properties();
prop.load(Demo.class.getResourceAsStream("druid.properties"));
DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
Connection conn = dataSource.getConnection();
System.out.println(conn);
}
}
工具类
public class DruidUtils {
private static DataSource dataSource;
static {
Properties prop = new Properties();
try {
prop.load(DruidUtils.class.getResourceAsStream("druid.properties"));
dataSource = DruidDataSourceFactory.createDataSource(prop);
} catch (Exception e) {
e.printStackTrace();
}
}
public static DataSource getDataSource() {
return dataSource;
}
public static Connection getConnection() {
try {
return dataSource.getConnection();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return null;
}
}
DBCP连接池
使用步骤:
-
导⼊jar包
commons-dbcp2-2.1.1.jar
commons-pool2-2.4.2.jar -
定义配置⽂件
配置⽂件名称:*.properties
配置⽂件位置:任意,建议src(classpath/类路径)
配置⽂件内容:#连接设置 driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/java2106 username=root password=123wang456 #初始化连接 initialSize=10 #最大连接数 maxActive=50 #最大空闲连接 maxIdle=20 #最小空闲连接 minIdle=5 #超时等待时间以毫秒为单位 maxWait=60000 #JDBC驱动建⽴连接时附带的连接属性属性的格式必须为这样:[属性名=property;] #注意:"user" 与 "password" 两个属性会被明确地传递,因此这⾥不需要包含他们。 connectionProperties=useUnicode=true;characterEncoding=gbk #ָ指定由连接池所创建的连接的自动提交状态 defaultAutoCommit=true #driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。 #可⽤值为下列之⼀:(详情可⻅javadoc。NONE,READ_UNCOMMITTED,READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE defaultTransactionIsolation=READ_UNCOMMITTED
-
加载配置⽂件。Properties
Properties pros = new Properties(); try { pros.load(DruidUtils.class.getResourceAsStream("dbcp.properties")); } catch (IOException e) { e.printStackTrace(); }
-
获取数据库连接池对象:通过⼯⼚来来获取 BasicDataSourceFactory
DataSource dataSource = BasicDataSourceFactory.createDataSource(pros)
public class Demo {
public static void main(String[] args) throws Exception {
Properties prop = new Properties();
prop.load(Demo.class.getResourceAsStream("dbcpconfig.properties"));
DataSource dataSource = BasicDataSourceFactory.createDataSource(prop);
System.out.println(dataSource);
}
}
工具类
public class DBCPUtils {
private static DataSource dataSource;
static {
Properties prop = new Properties();
try {
prop.load(DBCPUtils.class.getResourceAsStream("dbcpconfig.properties"));
} catch (IOException e) {
e.printStackTrace();
}
}
public static DataSource getDataSource() {
return dataSource;
}
public static Connection getConnection() {
try {
return dataSource.getConnection();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return null;
}
}
JdbcTemplate
概念
JdbcTemplate是通过 SQL 语句 + 参数,模板化了编程。它是 Spring 框架中提供的⼀个对象,是对原始 Jdbc API 对象的简单封装。除了 JdbcTemplate,Spring 框架还为我们提供了很多的操作模板类。
使用步骤
-
导⼊jar包
commons-logging-1.2.jar
spring-beans-5.2.6.RELEASE.jar
spring-core-5.2.6.RELEASE.jar
spring-jdbc-5.2.6.RELEASE.jar
spring-tx-5.2.6.RELEASE.jar -
创建JdbcTemplate对象。依赖于数据源DataSource
JdbcTemplate template = new JdbcTemplate(ds);
-
调⽤JdbcTemplate的⽅法来完成CRUD的操作
update():执⾏DML语句。增、删、改语句
queryForMap():查询结果将结果集封装为map集合,将列名作为key,将值作为value将这条记录封装为⼀个map集合
注意:这个⽅法查询的结果集⻓度只能是1
queryForList():查询结果将结果集封装为list集合
注意:将每⼀条记录封装为⼀个Map集合,再将Map集合装载到List集合中
query():查询结果,将结果封装为JavaBean对象
query的参数:RowMapper
⼀般我们使⽤ BeanPropertyRowMapper 实现类。可以完成数据到JavaBean 的⾃动封装
new BeanPropertyRowMapper<类型>(类型.class)
queryForObjec():查询结果,将结果封装为对象
⼀般⽤于聚合函数的查询public class Demo01 { public static void main(String[] args) { // jdbcTemplate - 基于数据源技术 JdbcTemplate jdbcTemplate = new JdbcTemplate(DruidUtils.getDataSource()); // 定义sql语句 String sql = "insert into user2 values(?,?,?)"; String sql1 = "delete from user2 where username = ?"; String sql2 = "update user2 set id = ? where username = ?"; // 执行sql语句 String uuid = UUID.randomUUID().toString().replaceAll("-",""); // jdbcTemplate.update(sql,uuid,"lucy","12345"); // jdbcTemplate.update(sql1,"lucy"); jdbcTemplate.update(sql2,"123","lucy"); } }