数据库连接池 简单实现(装饰设计模式)
若是不使用数据库连接池,需要频繁的创建和关闭连接,造成了资源的浪费

1、编写连接池
使用sun公司定义的连接池的规范 DataSource
其次使用properties文件来获取连接的数量与数据库的具体信息
public class MyDataSource implements DataSource {
//1、创建LinkedList作为连接池
private LinkedList<Connection> connections = new LinkedList();
//2、创建proporties集合读取properties文件
private static Properties configDB = new Properties();
//3、在静态代码块中读取文件加载驱动
static {
//p1、通过类加载器获取流
//先通过反射获取字节码文件的类加载器
//再通过getResourceAsStream方法将字节码文件以流的形式读入
InputStream in = MyDataSource.class.getClassLoader().getResourceAsStream("db.properties");
try {
//p2、加载properties文件
//调用load方法,将文件读入properties集合
configDB.load(in);
//p3、加载驱动
Class.forName(configDB.getProperty("driver"));
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//4、通过构造器建立连接(连接池)
public MyDataSource(){
//读取配置文件中的最大连接数量
int num = Integer.parseInt(configDB.getProperty("max"));
//for循环先创建好连接
for(int i=0;i<num;i++){
try {
Connection connection = DriverManager.getConnection(configDB.getProperty("url"),
configDB.getProperty("user"),configDB.getProperty("pwd"));
//加入连接池中
connections.add(connection);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//5、实现DataSource中的方法
//通过getConnection()方法返回一个对象
@Override
public Connection getConnection() throws SQLException {
//移除集合中第一个对象返回给客户
Connection conn = connections.removeFirst();
//因为Connection中close()方法本质是关闭连接
//所以需要重写Connection中的方法
return new MyConnection(conn);
}
2、包装设计模式
因为在外部用户使用完成后调用close()方法会直接关闭连接
思考:
1、获取Connection接口 自己写一个接口实现类---具体操作不现实
2、编写一个类继承mysql驱动的实现类,重写close方法---但是方法不具有通用性
3、设计模式 --具有可实现性
1)装饰设计模式(包装设计模式)
创建一个新类,包装原始类,从而在新类中提升原来类的功能
2)动态代理模式 在后面实现
1)装饰设计模式
//内部类实现Connection
class MyConnection implements Connection{
//通过构造器来绑定使用的conn对象
private Connection conn;
public MyConnection(Connection conn){
this.conn=conn;
}
//重写close()方法
@Override
public void close() throws SQLException {
//调用close()返回连接池
connections.add(conn);
}
//6、对于不想覆盖的方法直接调用被增强对象的方法来执行
@Override
public Statement createStatement() throws SQLException {
return conn.createStatement();
}
...
3、第三方数据库连接池的使用
1)C3P0的使用
导包

准备配置文件

<c3p0-config>
<!-- 使用默认的配置读取连接池对象 -->
<default-config>
<!-- 连接参数 -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/dormitory_management</property>
<property name="user">root</property>
<property name="password">admin</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/dormitory_management</property>
<property name="user">root</property>
<property name="password">root</property>
<!-- 连接池参数 -->
<property name="initialPoolSize">5</property>
<property name="maxPoolSize">8</property>
<property name="checkoutTimeout">1000</property>
</named-config>
</c3p0-config>
使用
//使用C3P0创建连接池
DataSource dataSource = new ComboPooledDataSource();
Connection connection = dataSource.getConnection();
System.out.println(connection);
//第二种方式创建
//使用别的数据库的配置文件
//在创建时写入configName即可
DataSource dataSource1 = new ComboPooledDataSource("otherc3p0");
Connection connection1 = dataSource.getConnection();
System.out.println(connection);
//第三种方式创建
//当没有xml文件时可以手动设置进去
ComboPooledDataSource dataSource2 = new ComboPooledDataSource();
dataSource2.setDriverClass("com.mysql.jdbc.Driver");
dataSource2.setJdbcUrl("jdbc:mysql://localhost:3306/dormitory_management");
dataSource2.setUser("root");
dataSource2.setPassword("root");
dataSource2.setMaxPoolSize(12);
dataSource2.setInitialPoolSize(5);
Connection connection2 = dataSource.getConnection();
System.out.println(connection);
connection.close();
2)Druid
详细使用在后面的文章中
导包

使用
public static void main(String[] args) throws SQLException {
DruidDataSource druidDataSource=new DruidDataSource();
druidDataSource.setDriverClassName("com.mysql.jdbc.Driver");
druidDataSource.setUrl("jdbc:mysql://localhost:3306/crud");
druidDataSource.setUsername("root");
druidDataSource.setPassword("root");
druidDataSource.setInitialSize(5);
druidDataSource.setMaxActive(12);
Connection connection = druidDataSource.getConnection();
System.out.println(connection);
connection.close();
}

浙公网安备 33010602011771号