JDBC连接池
JDBC连接池的概念
1.数据库连接的背景:
- 数据库连接是一种关键的、有限的、昂贵的资源,这一点在多用户的网页应用程序中体现得尤为突出
- 对数据库连接的管理能显著影响到整个应用程序的性能指标,数据库连接池正是针对这个问题提出来的.
2.数据库连接池
- 数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,
而不是再重新建立一个。这项技术能明显提高对数据库操作的性能
开源数据库连接池的使用
1. C3P0 数据库连接池的使用步骤。
① 导入 jar 包。
c3p0-0.9.5.2.jar
mchange-commons-java-0.2.12.jar
② 导入配置文件到 src 目录下。
配置信息:
<c3p0-config>
<!-- 使用默认的配置读取连接池对象 -->
<default-config>
<!-- 连接参数 -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://数据库ip:端口号/数据库名</property>
<property name="user">root</property>
<property name="password">root</property>
<!-- 连接池参数 -->
<!--初始化的连接数量-->
<property name="initialPoolSize">5</property>
<!--最大连接数量-->
<property name="maxPoolSize">10</property>
<!--超时时间-->
<property name="checkoutTimeout">3000</property>
</default-config>
<named-config name="otherc3p0">
<!-- 连接参数 -->
<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>
③ 创建 C3P0 连接池对象。
创建CombopooledDataSource对象
④ 获取数据库连接进行使用。
通过CombopooledDataSource对象名.getConnection()获取数据库连接
代码实现:
public class C3P0Test1 {
public static void main(String[] args) throws Exception{
//1.创建c3p0的数据库连接池对象
DataSource dataSource = new ComboPooledDataSource();
//2.通过连接池对象获取数据库连接
Connection con = dataSource.getConnection();
//3.执行操作
String sql = "SELECT * FROM student";
PreparedStatement pst = con.prepareStatement(sql);
//4.执行sql语句,接收结果集
ResultSet rs = pst.executeQuery();
//5.处理结果集
while(rs.next()) {
System.out.println(rs.getInt("sid") + "\t" + rs.getString("name") + "\t" + rs.getInt("age") + "\t" + rs.getDate("birthday"));
}
//6.释放资源
rs.close();
pst.close();
con.close();
}
}
注意:C3P0 的配置文件会自动加载,但是必须叫 c3p0-config.xml 或 c3p0-config.properties 。
2. Druid 数据库连接池的使用步骤:
① 导入 jar 包。
druid-1.0.9.jar
② 编写配置文件,放在 src 目录下。
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://数据库ip地址:端口号/数据库名
username=root
password=root
//初始化连接的数量
initialSize=5
//连接最大数量
maxActive=10
//连接超时时间
maxWait=3000
③ 通过 Properties 集合加载配置文件。
//获取配置文件的流对象
InputStream is = DruidTest1.class.getClassLoader().getResourceAsStream("druid.properties");
//1.通过Properties集合,加载配置文件
Properties prop = new Properties();
prop.load(is);
④ 通过 Druid 连接池工厂类获取数据库连接池对象。
//2.通过Druid连接池工厂类获取数据库连接池对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
//3.通过连接池对象获取数据库连接进行使用
Connection con = dataSource.getConnection();
⑤ 获取数据库连接进行使用。
整体实现代码:
package com.itheima04;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
/*
1.通过Properties集合,加载配置文件
2.通过Druid连接池工厂类获取数据库连接池对象
3.通过连接池对象获取数据库连接进行使用
*/
public class DruidTest1 {
public static void main(String[] args) throws Exception{
//获取配置文件的流对象
InputStream is = DruidTest1.class.getClassLoader().getResourceAsStream("druid.properties");
//1.通过Properties集合,加载配置文件
Properties prop = new Properties();
prop.load(is);
//2.通过Druid连接池工厂类获取数据库连接池对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
//3.通过连接池对象获取数据库连接进行使用
Connection con = dataSource.getConnection();
String sql = "SELECT * FROM student";
PreparedStatement pst = con.prepareStatement(sql);
//4.执行sql语句,接收结果集
ResultSet rs = pst.executeQuery();
//5.处理结果集
while(rs.next()) {
System.out.println(rs.getInt("sid") + "\t" + rs.getString("name") + "\t" + rs.getInt("age") + "\t" + rs.getDate("birthday"));
}
//6.释放资源
rs.close();
pst.close();
con.close();
}
}
注意:Druid 不会自动加载配置文件,需要我们手动加载,但是文件的名称可以自定义。
数据库连接池工具类
目的:
- 简化DataSource的创建步骤
- 方便维护,一个程序中只需要维护一个DataSource
步骤:
①私有工具类的构造方法
//1.私有构造方法
private DataSourceUtils(){}
②静态代码块中实现Datasource的初始化
- 加载配置文件
- 创建DataSource对象
//3.提供静态代码块,完成配置文件的加载和获取数据库连接池对象
static{
try{
//完成配置文件的加载
InputStream is = DataSourceUtils.class.getClassLoader().getResourceAsStream("druid.properties");
Properties prop = new Properties();
prop.load(is);
//获取数据库连接池对象
dataSource = DruidDataSourceFactory.createDataSource(prop);
} catch (Exception e) {
e.printStackTrace();
}
}
③提供getConnection方法
//4.提供一个获取数据库连接的方法
public static Connection getConnection() {
Connection con = null;
try {
con = dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return con;
}
④释放资源
public static void close(Connection con, Statement stat, ResultSet rs) {
if(con != null) {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(stat != null) {
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static void close(Connection con, Statement stat) {
if(con != null) {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(stat != null) {
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
代码优化后实现连接数据库查询
package com.itheima04;
import com.itheima.utils.DataSourceUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class DruidTest2 {
public static void main(String[] args) throws Exception{
//1.通过连接池工具类获取一个数据库连接
Connection con = DataSourceUtils.getConnection();
String sql = "SELECT * FROM student";
PreparedStatement pst = con.prepareStatement(sql);
//2.执行sql语句,接收结果集
ResultSet rs = pst.executeQuery();
//3.处理结果集
while(rs.next()) {
System.out.println(rs.getInt("sid") + "\t" + rs.getString("name") + "\t" + rs.getInt("age") + "\t" + rs.getDate("birthday"));
}
//4.释放资源
DataSourceUtils.close(con,pst,rs);
}
}
策略设计模式
- 执行者(谁执行策略)
package com.itheima.day02;
public class Athelete {
public void action(Action action){
action.yunDong();
}
}
- 策略(策略接口)
package com.itheima.day02;
public interface Action {
void yunDong();
}
- 调用者
package com.itheima.day02;
public class SportMany implements Action {
@Override
public void yunDong() {
System.out.println("运动");
}
}
- 测试类
package com.itheima.day02;
public class Main {
public static void main(String[] args) {
Athelete athelete = new Athelete();
athelete.action(new SportMany());
}
}
输出结果:
运动员收到运动指令,通过运动实现类获取运动项目.
在测试类中创建运动员对象,调用运动方法即可执行运动项目,
如需让运动员执行其他运动项目只需让调用者指定不用项目即可.