一、数据源的设计-->MyDataSource
class MyDataSource{
private static String url = "jdbc:mysql:///daxia";
private static String user = "root";
private static String password = "root";
//初始化连接数
private static int initCount = 3;
//最大连接数
private static int maxCount = 5;
//当前连接数
int currentCount = 0;
//对于操作对象的性能较ArrayList好
LinkedList<Connection> connectionsPool = new LinkedList<Connection>();
public MyDataSource() {
try {
for (int i = 0; i < initCount; i++) {
//把初始化的连接对象存放到链表里面
this.connectionsPool.addLast(this.createConnection());
this.currentCount++;
}
} catch (SQLException e) {
throw new ExceptionInInitializerError(e);
}
}
public Connection getConnection() throws SQLException {
synchronized (connectionsPool) {
if (this.connectionsPool.size() > 0)
//从链表里面删除头一个连接对象,并返回该连接对象
return this.connectionsPool.removeFirst();
if (this.currentCount < maxCount) {
this.currentCount++;
return this.createConnection();
}
throw new SQLException("已没有链接");
}
}
public void free(Connection conn) {
//释放连接,把当前连接加到链表尾,并没有真正关闭
this.connectionsPool.addLast(conn);
}
//父类引用指向子类对象
private Connection createConnection() throws SQLException {
Connection realConn = DriverManager.getConnection(url, user, password);
return new MyConnection(realConn, this);
}
}
二、代理连接类设计-->MyConnection
public class MyConnection implements Connection {
//真正的连接对象
private Connection realConnection; //组合
//数据源
private MyDataSource dataSource;
//连接使用的最大次数,超过这个次数,将真正关闭这个连接
private int maxUseCount = 5;
private int currentUserCount = 0;
MyConnection(Connection connection, MyDataSource dataSource) {
this.realConnection = connection;
this.dataSource = dataSource;
}
public void clearWarnings() throws SQLException {
this.realConnection.clearWarnings();
}
//我们关心的方法
public void close() throws SQLException {
this.currentUserCount++;
if (this.currentUserCount < this.maxUseCount)
//把代理Connection放进去,不要把真正的连接放回,这样这个方法才有效
this.dataSource.connectionsPool.addLast(this);
else {
this.realConnection.close();
this.dataSource.currentCount--;
}
}
public void commit() throws SQLException {
this.realConnection.commit();
}
public Statement createStatement() throws SQLException {
return this.realConnection.createStatement();
}
//其他方法略.........
}
三、jdbc工具类设计-->JdbcUtils
public final class JdbcUtils {
private static MyDataSource myDataSource = null;
private JdbcUtils() {
}
static {
try {
Class.forName("com.mysql.jdbc.Driver");// 只执行一次
//加载了驱动后才能实例化
myDataSource = new MyDataSource();
} catch (ClassNotFoundException e) {
throw new ExceptionInInitializerError(e);
}
}
public static Connection getConnection() throws SQLException {
return myDataSource.getConnection();
}
public static void free(Connection conn) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
四、 客户端测试类-->TestConnection
public class TestConnection{
public static void main(String[] args) {
try {
for(int i=0;i<20;i++){
Connection conn = JdbcUtils.getConnection();
System.out.println(conn);
JdbcUtils.free(conn);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
五、总结
MyDataSource类实例化后,会创建多个连接对象,并把这个对象存放到连接池(connectionsPool)里面去,方便以后的调用。由于创建连接对象比创建一般的对象的成本要高很多。所以MyDataSource类在程序中只实例化一次,即单例.
MyConnection 实现了java.sql.Connection类,Connection能做的MyConnection都能做.但我们关心的只有Connection接口的close方法.其他方法的实现真正的连接类realConnection去做.
MyDataSource与MyConnection 相对于客户端是透明的,客户端使用Connection接口引用MyConnection 对象!
分享到:
相关推荐
在本项目中,你将看到一个自定义的数据库连接池实现,它运用了代理模式以及面向接口编程的概念,旨在提供灵活、可扩展的解决方案。 首先,我们来详细讨论数据库连接池的工作原理。数据库连接池在初始化时会预创建...
在本主题“代理模式之静态代理---数据库连接池对象实现原理”中,我们将探讨如何使用静态代理来实现数据库连接池。数据库连接池是现代应用中常用的优化手段,它可以高效地管理数据库连接,避免频繁地创建和关闭连接...
在本项目中,可能会应用到工厂模式(用于创建数据库连接)、单例模式(确保数据库连接池在整个应用中只有一个实例)和代理模式(为数据库连接提供一个接口,便于管理和监控)等。 数据库连接池的核心是管理数据库...
在IT行业中,数据库连接池是优化数据库访问性能和资源...在实际开发中,有许多成熟的数据库连接池实现,如Apache的DBCP、C3P0和HikariCP等,它们都采用了类似的代理模式设计,提供了高效且可靠的数据库连接管理功能。
接下来,我们讨论连接池的设计思想。数据库连接池是一种池化技术,用于管理数据库连接,避免频繁地创建和销毁连接,从而提高性能。连接池的主要优点包括: 1. **资源重用**:连接池会预先创建并缓存一定数量的...
Binder连接池是一种设计模式,用于管理Binder对象的创建与复用。在传统的Binder通信中,每次请求服务时都会创建一个新的Binder代理对象,这可能导致系统资源的浪费。连接池通过存储已创建的Binder代理,避免了频繁的...
在这个项目中,你使用Java实现了一个自定义的数据库连接池,应用了代理模式来优化连接管理和提高性能。下面我们将深入探讨这个主题。 首先,让我们了解什么是数据库连接池。在传统的数据库操作中,每当有新的数据库...
Druid连接池是阿里巴巴团队开发的一款高效、功能丰富的数据库连接池组件。它在Java环境中被广泛应用于Web应用服务器,以优化数据库资源的管理,提高系统的性能和稳定性。在本压缩包中,包含的是`druid`项目的源代码...
设计模式是一种在特定情境下解决问题的通用可复用方案,例如工厂模式可以用于创建数据库连接,单例模式可以保证连接池在整个应用程序中只有一个实例,代理模式则可以用于管理数据库连接的获取和释放。通过合理运用...
1. **连接池概念**:连接池是一种对象池设计模式,主要用于管理数据库连接。它预先创建一定数量的连接,当需要时可以从池中获取,使用完毕后归还到池中,而不是直接关闭连接。 2. **JedisPool**:Jedis提供的连接池...
下面将分别对这两种模式进行详细解释,并结合手写的数据库连接池和动态代理模式的使用进行深入探讨。 首先,装饰模式是一种结构型设计模式,它的主要目的是在不改变原有对象接口的情况下,为对象添加新的功能或行为...
- **数据库操作**:数据库连接池就是一种典型的代理模式应用,它管理数据库连接,提供透明化的数据访问。 了解并熟练运用代理模式,能够使我们在设计和实现复杂系统时,更加灵活和高效地控制对象间的交互,提升软件...
4. **ForkingDB**: 专为多进程环境设计的数据库连接池,可以确保每个子进程都有自己的数据库连接副本,避免了进程间共享连接带来的问题。 接下来,我们看看`psycopg2-latest.tar.gz`。这通常是一个包含最新版本的...
3. 在数据库连接池管理中,工厂模式用于创建连接,而单例模式确保在整个应用程序中只有一个连接池实例,以优化资源使用。 通过学习和应用这些设计模式,开发者不仅可以提高代码的可读性、可维护性和可扩展性,还能...
在系统中,某些对象只需要一个实例,例如,线程池、缓存或者数据库连接池等。在本项目中,可能使用单例模式来创建和管理共享的西瓜市场资源,如数据存储或全局配置。 2. **代理模式**: 代理模式为一个对象提供一...
- **连接池的初始化和配置**:连接池需要一个工厂类来创建和初始化,通常使用单例模式确保只有一个实例。工厂类接收连接参数,如驱动名、URL、用户名和密码,用于创建和管理连接。 - **用户接口设计**:提供简单...
在软件设计模式中,"简单工厂"、"代理模式"和"单例模式"是非常重要的概念,它们在实际开发中有着广泛的应用。下面将详细解释这三个设计模式,并结合标签中的"源码"和"工具",探讨它们在实际项目中的应用。 首先,...
在本设计模式课程设计中,我们重点探讨了五个核心的设计模式:原型模式、单例模式、抽象工厂模式、代理模式和建造者模式。这些模式在Java编程中具有广泛的应用,能够帮助开发者创建更加灵活、可扩展和易于维护的代码...
例如,MVC模式在Web应用开发中非常常见,单例模式常用于日志服务、数据库连接池等需要全局唯一的场景,代理模式可以用于数据访问控制,工厂模式则用于解耦对象的创建和使用。通过学习和实践这些模式,开发者可以更好...