数据库连接池
1.数据库连接池概述
作用: 创建和管理连接对象
1.1.什么是连接池?
连接池指:创建一个池子(容器) , 专门用来管理连接对象
数据库的连接对象创建工作,比较消耗性能。
一开始现在内存中开辟一块空间(集合) , 一开先往池子里面放置多个连接对象。后面需要连接的话,直接从池子里面去。不要去自己创建连接了。 使用完毕, 要记得归还连接。确保连接对象能循环利用。
1.2.连接池的作用:
- 更快响应速度
连接池里的连接在一开始就已经创建好了,后面如果需要直接拿就可以了,无需创建。 - 资源的重复利用、避免重复创建对象
连接对象使用完毕后,再归还到池子中进行统一管理即可。
2.自定义数据库连接池
出现的问题:
- 需要额外记住 addBack方法
- 单例。
- 无法面向接口编程。
因为接口里面没有定义addBack方法。 - 怎么解决? 以addBack 为切入点。
2.1.解决自定义数据库连接池出现的问题。
由于多了一个addBack 方法,所以使用这个连接池的地方,需要额外记住这个方法,并且还不能面向接口编程。
我们打算修改接口中的那个close方法。 原来的Connection对象的close方法,是真的关闭连接。
打算修改这个close方法,以后在调用close, 并不是真的关闭,而是归还连接对象。
2.2.如何扩展某一个方法?
原有的方法逻辑,不是我们想要的。 想修改自己的逻辑
-
直接改源码 无法实现。
-
继承, 必须得知道这个接口的具体实现是谁。
-
使用装饰者模式。
2.3.代码实现
public class MyDataSource implements DataSource{
List<Connection> list = new ArrayList<Connection>();
public MyDataSource() {
for (int i = 0; i < 10; i++) {
Connection conn = JDBCUtil.getConn();
list.add(conn);
}
}
//该连接池对外公布的获取连接的方法
public Connection getConnection() throws SQLException {
//来拿连接的时候,看看,池子里面还有没有
if(list.size() == 0) {
for (int i = 0; i < 5; i++) {
Connection conn = JDBCUtil.getConn();
list.add(conn);
}
}
//remove(0)-->移除第一个。移除的是集合中的第一个
Connection conn = list.remove(0);
//在把这个对象抛出去的时候,对这个对象进行包装
Connection connection = new ConnectionWrap(conn, list);
return conn;
}
//归还连接
public void addBack(Connection conn) {
list.add(conn);
}
用装饰者模式包装
public class ConnectionWrap implements Connection{
Connection connection = null;
List<Connection> list;
public ConnectionWrap(Connection connection,List<Connection> list) {
super();
this.connection = connection;
}
public void close() throws SQLException {
//connection.close();
list.add(connection);
}
public PreparedStatement prepareStatement(String sql) throws SQLException
{
return connection.prepareStatement(sql);
}
3.开源连接池
3.1.DBCP
3.1.1.什么是DBCP?
DBCP(DataBase Connection Pool)数据库连接池,是java数据库连接池的一种,由Apache开发,通过数据库连接池,可以让程序自动管理数据库连接的释放和断开
3.1.2.怎么用DBCP?
-
导入jar文件
-
不使用配置文件:
public void testDBCP01(){
Connection conn = null;
PreparedStatement ps = null;
try {
//1. 构建数据源对象
BasicDataSource dataSource = new BasicDataSource();
//连的是什么类型的数据库, 访问的是哪个数据库 , 用户名, 密码。。
//jdbc:mysql://localhost/bank 主协议:子协议 ://本地/数据库
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost/bank");
dataSource.setUsername("root");
dataSource.setPassword("root");
//2. 得到连接对象
conn = dataSource.getConnection();
String sql = "insert into account values(null , ? , ?)";
ps = conn.prepareStatement(sql);
ps.setString(1, "admin");
ps.setInt(2, 1000);
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}finally {
JDBCUtil.release(conn, ps);
}
}
- 使用配置文件方式:
Connection conn = null;
PreparedStatement ps = null;
try {
BasicDataSourceFactory factory = new BasicDataSourceFactory();
Properties properties = new Properties();
InputStream is = new FileInputStream("src//dbcpconfig.properties");
properties.load(is);
DataSource dataSource = factory.createDataSource(properties);
//2. 得到连接对象
conn = dataSource.getConnection();
String sql = "insert into account values(null , ? , ?)";
ps = conn.prepareStatement(sql);
ps.setString(1, "liangchaowei");
ps.setInt(2, 100);
ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtil.release(conn, ps);
}
3.2.C3P0
3.2.1.什么是C3P0?
C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate,Spring等。
3.2.1.怎么用C3P0?
拷贝jar文件 到 lib目录
1.不使用配置文件方式
Connection conn = null;
PreparedStatement ps = null;
try {
//1. 创建datasource
ComboPooledDataSource dataSource = new ComboPooledDataSource();
//2. 设置连接数据的信息
dataSource.setDriverClass("com.mysql.jdbc.Driver");
//忘记了---> 去以前的代码 ---> jdbc的文档
dataSource.setJdbcUrl("jdbc:mysql://localhost/bank");
dataSource.setUser("root");
dataSource.setPassword("root");
//2. 得到连接对象
conn = dataSource.getConnection();
String sql = "insert into account values(null , ? , ?)";
ps = conn.prepareStatement(sql);
ps.setString(1, "admi234n");
ps.setInt(2, 103200);
ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtil.release(conn, ps);
}
2.使用配置文件方式
//默认会找 xml 中的 default-config 分支。
ComboPooledDataSource dataSource = new ComboPooledDataSource();
//2. 设置连接数据的信息
dataSource.setDriverClass("com.mysql.jdbc.Driver");
//忘记了---> 去以前的代码 ---> jdbc的文档
dataSource.setJdbcUrl("jdbc:mysql://localhost/bank");
dataSource.setUser("root");
dataSource.setPassword("root");
//2. 得到连接对象
conn = dataSource.getConnection();
String sql = "insert into account values(null , ? , ?)";
ps = conn.prepareStatement(sql);
ps.setString(1, "admi234n");
ps.setInt(2, 103200);