1 连接池的概念和作用
问题:连接池的本质是什么?有什么作用?
- 概念:连接池的本质就是一个容器,该容器中会初始化一些Connection对象,我们程序只需要从连接池中获取连接,使用完毕之后归还连接即可。
- 作用:大大减少了频繁的创建和释放连接的时间,提高数据库操作的效率
2.c3p0连接池[用的不多]
【1】使用步骤
【前提】导入c3p0依赖jar包[以及连接mysql-connector-java-5.1.47.jar]
c3p0-0.9.5.2.jar、mchange-commons-java-0.2.12.jar
【第一步】将c3p0-config.xml配置文件复制到src中(位置和名称是固定的)
【第二步】创建ComboPooledDataSource核心对象
【第三步】获取连接
【2】src目录下的属性配置文件写法
注意:如果两种配置文件都存在,优先使用xml配置文件。
<1>用c3p0-config.xml配置
c3p0-config.xml的配置文件的名称和位置是固定的,配置文件放在src目录中,配置文件中的属性名也是固定的,否则无法根据属性名或者对应的属性值。
<c3p0-config>
<!-- 使用默认的配置读取连接池对象 -->
<default-config>
<!-- 连接参数 -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbc</property>
<property name="user">root</property>
<property name="password">123456</property>
<!-- 连接池参数 -->
<!-- 初始化的连接数量-->
<property name="initialPoolSize">5</property>
<!-- 最大连接数量-->
<property name="maxPoolSize">10</property>
<!-- 超时时间-->
<property name="checkoutTimeout">3000</property>
</default-config>
<named-config name="oracle">
<!-- 连接参数 -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/db15</property>
<property name="user">root</property>
<property name="password">itheima</property>
<!-- 连接池参数 -->
<property name="initialPoolSize">5</property>
<property name="maxPoolSize">8</property>
<property name="checkoutTimeout">1000</property>
</named-config>
</c3p0-config>
<2>用c3p0.properties配置
属性文件的名称必须是c3p0.properties,必须放在src路径下,文件中的key是固定的,必须以c3p0.开头
#下面为mysql5.0版本 8.0版本为com.mysql.cj.jdbc.Driver
c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql://localhost/jdbc
c3p0.user=root
c3p0.password=123456
#最大连接数
c3p0.maxPoolSize=10
#超时时间单位为毫秒
c3p0.checkoutTimeout=3000
【3】c3p0连接实现代码
由于最大连接数为10,而又设置了1和10归还连接,则i=1和10会重复使用,且不会超过上限等待超时
import com.mchange.v2.c3p0.ComboPooledDataSource;
import java.sql.Connection;
import java.sql.SQLException;
public class C3p0DataSourceDemo {
public static void main(String[] args) throws SQLException {
//1.创建连接池对象
ComboPooledDataSource dataSource = new ComboPooledDataSource();
//可通过配置名获取哦配置参数 上面为默认
//ComboPooledDataSource dataSource = new ComboPooledDataSource("oracle");
//2.获取连接
//测试
for (int i = 1; i <= 12; i++) {
Connection conn = dataSource.getConnection();
System.out.println(i+","+conn);
if(i==1||i==10){
conn.close();
}
}
// 获取连接池的其他参数
//获取最大连接数
System.out.println("最大连接数:"+dataSource.getMaxPoolSize());
}
}
打印结果:
------------------------------------------------------------------------------------------
1,com.mchange.v2.c3p0.impl.NewProxyConnection@1534f01b [wrapping: com.mysql.jdbc.JDBC4Connection@78e117e3]
2,com.mchange.v2.c3p0.impl.NewProxyConnection@79b06cab [wrapping: com.mysql.jdbc.JDBC4Connection@3eb7fc54]
3,com.mchange.v2.c3p0.impl.NewProxyConnection@3c22fc4c [wrapping: com.mysql.jdbc.JDBC4Connection@78e117e3]
4,com.mchange.v2.c3p0.impl.NewProxyConnection@47d90b9e [wrapping: com.mysql.jdbc.JDBC4Connection@1184ab05]
5,com.mchange.v2.c3p0.impl.NewProxyConnection@149e0f5d [wrapping: com.mysql.jdbc.JDBC4Connection@1b1473ab]
6,com.mchange.v2.c3p0.impl.NewProxyConnection@6af93788 [wrapping: com.mysql.jdbc.JDBC4Connection@ef9296d]
7,com.mchange.v2.c3p0.impl.NewProxyConnection@7880cdf3 [wrapping: com.mysql.jdbc.JDBC4Connection@5be6e01c]
8,com.mchange.v2.c3p0.impl.NewProxyConnection@6ef888f6 [wrapping: com.mysql.jdbc.JDBC4Connection@10e92f8f]
9,com.mchange.v2.c3p0.impl.NewProxyConnection@78b66d36 [wrapping: com.mysql.jdbc.JDBC4Connection@5223e5ee]
10,com.mchange.v2.c3p0.impl.NewProxyConnection@69b2283a [wrapping: com.mysql.jdbc.JDBC4Connection@22a637e7]
11,com.mchange.v2.c3p0.impl.NewProxyConnection@1d119efb [wrapping: com.mysql.jdbc.JDBC4Connection@659a969b]
12,com.mchange.v2.c3p0.impl.NewProxyConnection@2473d930 [wrapping: com.mysql.jdbc.JDBC4Connection@22a637e7]
最大连接数:10
3.Druid连接池[常用]
【1】使用步骤
【前提】导入druid依赖jar包[以及连接mysql-connector-java-5.1.47.jar]
【第一步】在src编写配置文件,名称任意,一般叫做druid.properties
【第二步】使用Properties对象加载配置文件
【第三步】使用DruidDataSourceFactory工厂创建连接池对象
【第四步】获取连接
【2】src目录下的属性配置文件内容
#key是固定的,value根据实际情况修改
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbc
username=root
password=123456
# 初始化连接数量
initialSize=5
# 最大连接数
maxActive=10
# 等待超时时间
maxWait=3000
在src编写配置文件,名称任意,一般叫做druid.properties
【3】druid连接操纵数据库实现代码
import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.itheima.domain.Student;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Properties;
public class DruidDemo1 {
public static void main(String[] args) throws Exception {
//方式一:通过DruidDataSourceFactory对象创建连接池对象
//1.通过Properties集合,加载druid.properties配置文件
Properties properties = new Properties();
//通过累加器获取类路径下(src)的文件输入流
InputStream is = DruidDemo1.class.getClassLoader().getResourceAsStream("druid.properties");
properties.load(is);
//2.通过Druid连接池工厂类获取数据库连接池对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
//3.通过连接池对象获取数据库连接进行使用
Connection conn = dataSource.getConnection();
System.out.println(conn);
/* //方式二:直接new DruidDataSource连接池对象,硬编码。[了解]
//创建连接池对象
DruidDataSource dataSource = new DruidDataSource();
//设置参数
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/jdbc");
dataSource.setUsername("root");
dataSource.setPassword("123456");
//获取连接
DruidPooledConnection conn = dataSource.getConnection();*/
//4.执行sql语句,接收结果集
ArrayList<Student> list = new ArrayList<>();
//获取执行对象
PreparedStatement pstm = conn.prepareStatement("select * from student");
//执行操作,获取结果
ResultSet rs = pstm.executeQuery();
//处理结果
while (rs.next()) {
int sid = rs.getInt("sid");
String name = rs.getString("name");
int age = rs.getInt("age");
String birthday = rs.getString("birthday");
//封住到list集合
Student stu = new Student(sid, name, age, birthday);
list.add(stu);
}
list.forEach(student -> System.out.println(student));
rs.close();
conn.close();
//如果连接对象是从连接池中获取的,那么连接的close方法就不是关闭而是归还。
pstm.close();
}
}
打印结果:
------------------------------------------------------------------------------------------
com.mysql.jdbc.JDBC4Connection@551bdc27
Student{sid=1, name='张三', age=23, birthday='1999-09-23'}
Student{sid=2, name='李四', age=24, birthday='1998-08-10'}
Student{sid=3, name='王五', age=25, birthday='1996-06-06'}
Student{sid=4, name='赵六', age=26, birthday='1994-10-20'}
4连接池工具类的书写
目的:将DruidDataSource连接池封装进来,对外提供获取连接和释放资源的代码
/*
目的:将DruidDataSource连接池封装进来,对外提供获取连接和释放资源的代码
*/
public class DruidDataSource {
private static DataSource dataSource;
static {
try {
//1.加载druid.properties属性文件(一次)
Properties properties = new Properties();
InputStream is = DruidDataSource.class.getClassLoader().getResourceAsStream("druid.properties");
properties.load(is);
//2.创建DruidDataSource连接池对象(一次)
dataSource = DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
//3.对外提供获取连接池的方法
public static DataSource getDataSource(){
return dataSource;
}
//4.对外提供一个方法,获取连接
public static Connection getConnection() throws SQLException{
return dataSource.getConnection();
}
//5.对外提供一个方法释放资源,同时规划连接
public static void close(Connection conn, Statement stat, ResultSet rs){
try {
if (rs != null) {
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (rs != null) {
stat.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (rs != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
druid获取连接测试代码
import com.itheima.domain.Student;
import com.itheima.utils.DruidDataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
public class DruidDemo2 {
public static void main(String[] args) throws Exception {
Connection conn = DruidDataSource.getConnection();
//4.执行sql语句,接收结果集
ArrayList<Student> list = new ArrayList<>();
//获取执行对象
PreparedStatement pstm = conn.prepareStatement("select * from student");
//执行操作,获取结果
ResultSet rs = pstm.executeQuery();
//处理结果
while (rs.next()) {
int sid = rs.getInt("sid");
String name = rs.getString("name");
int age = rs.getInt("age");
String birthday = rs.getString("birthday");
//封住到list集合
Student stu = new Student(sid, name, age, birthday);
list.add(stu);
}
list.forEach(student -> System.out.println(student));
//如果连接对象是从连接池中获取的,那么连接的close方法就不是关闭而是归还。
DruidDataSource.close(conn,pstm,rs);
}
}
打印结果:
------------------------------------------------------------------------------------------
com.mysql.jdbc.JDBC4Connection@58fdd99
Student{sid=1, name='张三', age=23, birthday='1999-09-23'}
Student{sid=2, name='李四', age=24, birthday='1998-08-10'}
Student{sid=3, name='王五', age=25, birthday='1996-06-06'}
Student{sid=4, name='赵六', age=26, birthday='1994-10-20'}