- 浏览: 1636 次
- 性别:
- 来自: 天津
最近访客 更多访客>>
文章分类
最新评论
-
rhythm_01:
kimmking 写道个人觉得,一个数据库连接池,必须是非侵入 ...
写了一个简单的数据库连接池,请帮忙看一下 -
xika.xiang:
学习了原理,对连接池还还没深入过
写了一个简单的数据库连接池,请帮忙看一下 -
nianien:
yy59750901 写道 /**
* 获取一个可用链接
...
写了一个简单的数据库连接池,请帮忙看一下 -
ymkyve:
javaso 写道实现DataSource
头像把偶误导了, ...
写了一个简单的数据库连接池,请帮忙看一下 -
yy59750901:
qqggcc 写道<DBConfig>
&l ...
写了一个简单的数据库连接池,请帮忙看一下
我是一个新手,第一次发帖,以前都是看别人的帖子。
我写了一个简单的数据库连接池实现,感觉有很多欠缺的地方,希望各位指点一下。十分感谢。
有四个类:
(1)连接池配置对象 Config
(2)连接池主类 ConnectionPool
(3)Properties读取类 PropertyReader
(4)异常类 DBPoolException
ConnectionPool.java
Config.java
PropertyReader.java
DBPoolException .java
properties配置文件
我靠 你个大便男
我刚写了个简单的连接池。
等我花点时间写点原理性的东西,一起发出来。
我靠 你个大便男
多谢指点!!
连接池,首先可以控制资源个数,以后避免创建。
用完的资源,可以再放到池中使用。
支持多个线程并发获取资源。
池中满了,并且所有资源都处于忙的状态,
某个线程获取不用资源时,应该锁住线程,重试直到超时未知。
此外,某个资源,长期空闲,应该被回收掉。
定时检查资源是否已经不可用(connection isClosed),从池中去掉。
我一时能想到的,大概就这么多吧。
多谢指点!!
是是!!忘了!多谢
正解。。。。
首先 谢谢你的耐心观看 和 回复
我是通过properties来改变数据库的driver,就在最下面的properties配置文件中,如下:
不知道我说的是不是你的意思。
明显不是我的意思。
前几天也有人发了一个连接池。跟你这个几乎一样。
啊。。是么。。。
那你的意思我没太明白,像我这样,只要把各种数据库的驱动放进去,然后通过修改properties不就能达到变换数据库的作用么,取得连接只需要 ConnectionPool.getConn();就可以了。
我的意思是,我现在用jdbc或其他连接池写了个程序,
替换成你的连接池,不需要改我原来的代码。
明白点你的意思了 。。。
是说普通jdbc:
CLass.forName(driver);
现在我写一个类似driver的东西么?加载这个driver之后
原来的 DriverManager.getConnection(url,name,password);
取得就是我这个driver弄出来的一个连接?
这个确实很高深!!
DriverManager.getConnection(url,name,password);的机制我还没研究过。。
感觉很复杂 像写一个数据库驱动一样。。
首先 谢谢你的耐心观看 和 回复
我是通过properties来改变数据库的driver,就在最下面的properties配置文件中,如下:
不知道我说的是不是你的意思。
明显不是我的意思。
前几天也有人发了一个连接池。跟你这个几乎一样。
啊。。是么。。。
那你的意思我没太明白,像我这样,只要把各种数据库的驱动放进去,然后通过修改properties不就能达到变换数据库的作用么,取得连接只需要 ConnectionPool.getConn();就可以了。
我的意思是,我现在用jdbc或其他连接池写了个程序,
替换成你的连接池,不需要改我原来的代码。
首先 谢谢你的耐心观看 和 回复
我是通过properties来改变数据库的driver,就在最下面的properties配置文件中,如下:
不知道我说的是不是你的意思。
明显不是我的意思。
前几天也有人发了一个连接池。跟你这个几乎一样。
啊。。是么。。。
那你的意思我没太明白,像我这样,只要把各种数据库的驱动放进去,然后通过修改properties不就能达到变换数据库的作用么,取得连接只需要 ConnectionPool.getConn();就可以了。
首先 谢谢你的耐心观看 和 回复
我是通过properties来改变数据库的driver,就在最下面的properties配置文件中,如下:
不知道我说的是不是你的意思。
明显不是我的意思。
前几天也有人发了一个连接池。跟你这个几乎一样。
首先 谢谢你的耐心观看 和 回复
我是通过properties来改变数据库的driver,就在最下面的properties配置文件中,如下:
不知道我说的是不是你的意思。
那必须的。。。。
我写了一个简单的数据库连接池实现,感觉有很多欠缺的地方,希望各位指点一下。十分感谢。
有四个类:
(1)连接池配置对象 Config
(2)连接池主类 ConnectionPool
(3)Properties读取类 PropertyReader
(4)异常类 DBPoolException
ConnectionPool.java
public class ConnectionPool { private static Logger logger = Logger.getLogger(ConnectionPool.class); //当前已用连接数 private static volatile int curConnections = 0; private static Config config = null; //初始化成功标志 private static boolean initFlag = false; private static volatile Stack<Connection> conns; static { PropertyReader pr = null; try { pr = new PropertyReader("pool-config.properties"); config = new Config(); //设置数据库驱动 config.setDriver(pr.getValue("driver")); //url config.setUrl(pr.getValue("url")); //uername config.setUsername(pr.getValue("username")); //password config.setPassword(pr.getValue("password")); //最大连接数 if(pr.getValue("maxConnections") != null){ config.setMaxConnections(Integer.valueOf(pr.getValue("maxConnections"))); } //初始化时最小连接数 if(pr.getValue("minConnections") != null){ config.setMinConnections(Integer.valueOf(pr.getValue("minConnections"))); } //返还连接时是否提交 if(pr.getValue("autoCommitOnClose") != null){ config.setAutoCommitOnClose(Boolean.valueOf(pr.getValue("autoCommitOnClose"))); } //当连接池用完时客户端调用getConn()后等待获取新连接的时间 //Default: (100毫秒) if(pr.getValue("checkoutTimeout") != null){ config.setCheckoutTimeout(Integer.valueOf(pr.getValue("checkoutTimeout"))); } //当没有可用链接时,尝试获取链接的次数 if(pr.getValue("checkTimes") != null){ config.setCheckTimes(Integer.valueOf(pr.getValue("checkTimes"))); } initPool(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } /** * 隐藏构造函数 */ private ConnectionPool(){ } /** * 初始化连接池 保存minConnections个链接 * @throws SQLException * @throws ClassNotFoundException */ private static synchronized void initPool() throws SQLException, ClassNotFoundException{ conns = new Stack<Connection>(); Class.forName(config.getDriver()); for(int i = 0 ; i < config.getMinConnections() ; i++){ Connection conn = newConnection(); conns.push(conn); } initFlag = true; } /** * 获取一个可用链接 * @return * @throws SQLException * @throws InterruptedException * @throws DBPoolException * @throws Exception */ public static Connection getConn() throws SQLException, InterruptedException, DBPoolException { Connection conn = null; if (initFlag) { synchronized (conns) { // 循环次数 int times = 0; while (null == conn && times < config.getCheckTimes() + 1) { times++; // 如果未达到最大链接 if (curConnections < config.getMaxConnections()) { // 栈中未空 if (!conns.isEmpty()) { conn = conns.pop(); // 如果返回的链接不可用 if (null == conn || conn.isClosed()) { conn = newConnection(); } // 栈中空了 } else { conn = newConnection(); } } else { conns.wait(config.getCheckoutTimeout()); } } if(null == conn){ logger.warn("获取链接超时!!!!!"); throw new DBPoolException("获取链接超时!!!!!"); }else{ curConnections++; conns.notifyAll(); } } } else { logger.error("连接池初始化失败!!!!"); throw new DBPoolException("连接池初始化失败!!!!"); } return conn; } /** * 归还一个链接 * @param conn * @throws SQLException * @throws InterruptedException */ public static void returnConn(Connection conn) throws SQLException, InterruptedException { synchronized (conns) { if (null != conn && !conn.isClosed()) { // 如果设置归还前自动提交为真 if (config.isAutoCommitOnClose()) { conn.commit(); } else { conn.rollback(); } } int times = 0; //尝试归还5次 如果归还失败则关闭连接 while (times < 6) { times++; if (curConnections > 0 && curConnections <= config.getMaxConnections()) { conns.push(conn); curConnections--; break; } else if (curConnections == 0) { conns.wait(1000); } else { if(conn!=null && !conn.isClosed()) conn.close(); curConnections--; break; } } if(times == 5 && conn != null && !conn.isClosed()){ conn.close(); } conns.notifyAll(); } } /** * 简单的创建一个链接 * @return * @throws SQLException */ private static Connection newConnection() throws SQLException{ return DriverManager.getConnection(config.getUrl(),config.getUsername(),config.getPassword()); } /** * 获取已使用的连接数 * @return */ public static int getCurConnections() { return curConnections; } }
Config.java
public class Config { private String driver; private String url; private String username; private String password; private int minConnections = 10; private int maxConnections = 20; private boolean autoCommitOnClose = true; private int checkoutTimeout = 100; private int checkTimes = 10; public String getDriver() { return driver; } public void setDriver(String driver) { this.driver = driver; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public int getMinConnections() { return minConnections; } public void setMinConnections(int minConnections) { this.minConnections = minConnections; } public int getMaxConnections() { return maxConnections; } public void setMaxConnections(int maxConnections) { this.maxConnections = maxConnections; } public boolean isAutoCommitOnClose() { return autoCommitOnClose; } public void setAutoCommitOnClose(boolean autoCommitOnClose) { this.autoCommitOnClose = autoCommitOnClose; } public int getCheckoutTimeout() { return checkoutTimeout; } public void setCheckoutTimeout(int checkoutTimeout) { this.checkoutTimeout = checkoutTimeout; } public int getCheckTimes() { return checkTimes; } public void setCheckTimes(int checkTimes) { this.checkTimes = checkTimes; } }
PropertyReader.java
public class PropertyReader { Logger log = Logger.getLogger(PropertyReader.class); Properties props = null; public PropertyReader(String path) throws IOException{ props = new Properties(); try { props.load(getClass().getClassLoader().getResourceAsStream(path)); } catch (IOException e) { log.error("读取properties失败"); throw e; } } public String getValue(String key){ return props.getProperty(key); } }
DBPoolException .java
public class DBPoolException extends Throwable { public DBPoolException(String str){ super(str); } }
properties配置文件
driver=oracle.jdbc.driver.OracleDriver url=jdbc:oracle:thin:@localhost:1521:orcl username=test password=password minConnections=10 maxConnections=30 #当链接关闭的时候自动将未提交的内容提交 autoCommitOnClose=false #当连接池用完时客户端调用getConn()后等待获取新连接的时间,Default: (100毫秒) checkoutTimeout=100 #当没有可用链接时,尝试获取链接的次数 checkTimes=30
评论
17 楼
kimmking
2011-03-13
yy59750901 写道
whaosoft 写道
支持一下 羊驼吧 大家记住啊 lz是可爱的 羊驼驼
我靠 你个大便男
我刚写了个简单的连接池。
等我花点时间写点原理性的东西,一起发出来。
16 楼
yy59750901
2011-03-13
whaosoft 写道
支持一下 羊驼吧 大家记住啊 lz是可爱的 羊驼驼
我靠 你个大便男
15 楼
whaosoft
2011-03-12
支持一下 羊驼吧 大家记住啊 lz是可爱的 羊驼驼
14 楼
kgd1120
2011-03-12
客户端调用close方法会发生什么现象?returnConn是什么时候调用呢?
数据库连接池的核心之一是客户端透明,当客户端调用close方法时返还Connection对象
数据库连接池的核心之一是客户端透明,当客户端调用close方法时返还Connection对象
13 楼
kimmking
2011-03-12
yy59750901 写道
javaso 写道
实现DataSource
多谢指点!!
连接池,首先可以控制资源个数,以后避免创建。
用完的资源,可以再放到池中使用。
支持多个线程并发获取资源。
池中满了,并且所有资源都处于忙的状态,
某个线程获取不用资源时,应该锁住线程,重试直到超时未知。
此外,某个资源,长期空闲,应该被回收掉。
定时检查资源是否已经不可用(connection isClosed),从池中去掉。
我一时能想到的,大概就这么多吧。
12 楼
yy59750901
2011-03-12
javaso 写道
实现DataSource
多谢指点!!
11 楼
yy59750901
2011-03-12
wing5jface 写道
如果使用的某一个数据库连接未归还,超过一定时间,没有相关的线程代码监控?
是是!!忘了!多谢
10 楼
kimmking
2011-03-12
javaso 写道
实现DataSource
正解。。。。
9 楼
javaso
2011-03-12
实现DataSource
8 楼
wing5jface
2011-03-12
如果使用的某一个数据库连接未归还,超过一定时间,没有相关的线程代码监控?
7 楼
yy59750901
2011-03-12
kimmking 写道
yy59750901 写道
kimmking 写道
yy59750901 写道
kimmking 写道
个人觉得,一个数据库连接池,必须是非侵入性的,和jdbc本身兼容。
即我只需要把jdbc/datasource配置改成连接池的设置,
原来用jdbc写的代码什么都不用改。
比如只换掉一个jdbc driver类。
即我只需要把jdbc/datasource配置改成连接池的设置,
原来用jdbc写的代码什么都不用改。
比如只换掉一个jdbc driver类。
首先 谢谢你的耐心观看 和 回复
我是通过properties来改变数据库的driver,就在最下面的properties配置文件中,如下:
driver=oracle.jdbc.driver.OracleDriver url=jdbc:oracle:thin:@localhost:1521:orcl username=test password=password minConnections=10 maxConnections=30 #当链接关闭的时候自动将未提交的内容提交 autoCommitOnClose=false #当连接池用完时客户端调用getConn()后等待获取新连接的时间,Default: (100毫秒) checkoutTimeout=100 #当没有可用链接时,尝试获取链接的次数 checkTimes=30
不知道我说的是不是你的意思。
明显不是我的意思。
前几天也有人发了一个连接池。跟你这个几乎一样。
啊。。是么。。。
那你的意思我没太明白,像我这样,只要把各种数据库的驱动放进去,然后通过修改properties不就能达到变换数据库的作用么,取得连接只需要 ConnectionPool.getConn();就可以了。
我的意思是,我现在用jdbc或其他连接池写了个程序,
替换成你的连接池,不需要改我原来的代码。
明白点你的意思了 。。。
是说普通jdbc:
CLass.forName(driver);
现在我写一个类似driver的东西么?加载这个driver之后
原来的 DriverManager.getConnection(url,name,password);
取得就是我这个driver弄出来的一个连接?
这个确实很高深!!
DriverManager.getConnection(url,name,password);的机制我还没研究过。。
感觉很复杂 像写一个数据库驱动一样。。
6 楼
kimmking
2011-03-12
yy59750901 写道
kimmking 写道
yy59750901 写道
kimmking 写道
个人觉得,一个数据库连接池,必须是非侵入性的,和jdbc本身兼容。
即我只需要把jdbc/datasource配置改成连接池的设置,
原来用jdbc写的代码什么都不用改。
比如只换掉一个jdbc driver类。
即我只需要把jdbc/datasource配置改成连接池的设置,
原来用jdbc写的代码什么都不用改。
比如只换掉一个jdbc driver类。
首先 谢谢你的耐心观看 和 回复
我是通过properties来改变数据库的driver,就在最下面的properties配置文件中,如下:
driver=oracle.jdbc.driver.OracleDriver url=jdbc:oracle:thin:@localhost:1521:orcl username=test password=password minConnections=10 maxConnections=30 #当链接关闭的时候自动将未提交的内容提交 autoCommitOnClose=false #当连接池用完时客户端调用getConn()后等待获取新连接的时间,Default: (100毫秒) checkoutTimeout=100 #当没有可用链接时,尝试获取链接的次数 checkTimes=30
不知道我说的是不是你的意思。
明显不是我的意思。
前几天也有人发了一个连接池。跟你这个几乎一样。
啊。。是么。。。
那你的意思我没太明白,像我这样,只要把各种数据库的驱动放进去,然后通过修改properties不就能达到变换数据库的作用么,取得连接只需要 ConnectionPool.getConn();就可以了。
我的意思是,我现在用jdbc或其他连接池写了个程序,
替换成你的连接池,不需要改我原来的代码。
5 楼
yy59750901
2011-03-12
kimmking 写道
yy59750901 写道
kimmking 写道
个人觉得,一个数据库连接池,必须是非侵入性的,和jdbc本身兼容。
即我只需要把jdbc/datasource配置改成连接池的设置,
原来用jdbc写的代码什么都不用改。
比如只换掉一个jdbc driver类。
即我只需要把jdbc/datasource配置改成连接池的设置,
原来用jdbc写的代码什么都不用改。
比如只换掉一个jdbc driver类。
首先 谢谢你的耐心观看 和 回复
我是通过properties来改变数据库的driver,就在最下面的properties配置文件中,如下:
driver=oracle.jdbc.driver.OracleDriver url=jdbc:oracle:thin:@localhost:1521:orcl username=test password=password minConnections=10 maxConnections=30 #当链接关闭的时候自动将未提交的内容提交 autoCommitOnClose=false #当连接池用完时客户端调用getConn()后等待获取新连接的时间,Default: (100毫秒) checkoutTimeout=100 #当没有可用链接时,尝试获取链接的次数 checkTimes=30
不知道我说的是不是你的意思。
明显不是我的意思。
前几天也有人发了一个连接池。跟你这个几乎一样。
啊。。是么。。。
那你的意思我没太明白,像我这样,只要把各种数据库的驱动放进去,然后通过修改properties不就能达到变换数据库的作用么,取得连接只需要 ConnectionPool.getConn();就可以了。
4 楼
kimmking
2011-03-12
yy59750901 写道
kimmking 写道
个人觉得,一个数据库连接池,必须是非侵入性的,和jdbc本身兼容。
即我只需要把jdbc/datasource配置改成连接池的设置,
原来用jdbc写的代码什么都不用改。
比如只换掉一个jdbc driver类。
即我只需要把jdbc/datasource配置改成连接池的设置,
原来用jdbc写的代码什么都不用改。
比如只换掉一个jdbc driver类。
首先 谢谢你的耐心观看 和 回复
我是通过properties来改变数据库的driver,就在最下面的properties配置文件中,如下:
driver=oracle.jdbc.driver.OracleDriver url=jdbc:oracle:thin:@localhost:1521:orcl username=test password=password minConnections=10 maxConnections=30 #当链接关闭的时候自动将未提交的内容提交 autoCommitOnClose=false #当连接池用完时客户端调用getConn()后等待获取新连接的时间,Default: (100毫秒) checkoutTimeout=100 #当没有可用链接时,尝试获取链接的次数 checkTimes=30
不知道我说的是不是你的意思。
明显不是我的意思。
前几天也有人发了一个连接池。跟你这个几乎一样。
3 楼
yy59750901
2011-03-12
kimmking 写道
个人觉得,一个数据库连接池,必须是非侵入性的,和jdbc本身兼容。
即我只需要把jdbc/datasource配置改成连接池的设置,
原来用jdbc写的代码什么都不用改。
比如只换掉一个jdbc driver类。
即我只需要把jdbc/datasource配置改成连接池的设置,
原来用jdbc写的代码什么都不用改。
比如只换掉一个jdbc driver类。
首先 谢谢你的耐心观看 和 回复
我是通过properties来改变数据库的driver,就在最下面的properties配置文件中,如下:
driver=oracle.jdbc.driver.OracleDriver url=jdbc:oracle:thin:@localhost:1521:orcl username=test password=password minConnections=10 maxConnections=30 #当链接关闭的时候自动将未提交的内容提交 autoCommitOnClose=false #当连接池用完时客户端调用getConn()后等待获取新连接的时间,Default: (100毫秒) checkoutTimeout=100 #当没有可用链接时,尝试获取链接的次数 checkTimes=30
不知道我说的是不是你的意思。
2 楼
chenchao051
2011-03-12
kimmking 写道
个人觉得,一个数据库连接池,必须是非侵入性的,和jdbc本身兼容。
即我只需要把jdbc/datasource配置改成连接池的设置,
原来用jdbc写的代码什么都不用改。
比如只换掉一个jdbc driver类。
即我只需要把jdbc/datasource配置改成连接池的设置,
原来用jdbc写的代码什么都不用改。
比如只换掉一个jdbc driver类。
那必须的。。。。
1 楼
kimmking
2011-03-12
个人觉得,一个数据库连接池,必须是非侵入性的,和jdbc本身兼容。
即我只需要把jdbc/datasource配置改成连接池的设置,
原来用jdbc写的代码什么都不用改。
比如只换掉一个jdbc driver类。
即我只需要把jdbc/datasource配置改成连接池的设置,
原来用jdbc写的代码什么都不用改。
比如只换掉一个jdbc driver类。
相关推荐
2、**本次更新的数据库池支持现在设定的多个数据库同时在线。 3、**优化链接数据库速度提升。 ================ [2020-1-5日] ================ 1、**修正服务端连续读数据时崩溃问题,感谢群友(无极)帮忙测试,...
当应用程序需要确保某些资源只被创建一次时,比如数据库连接池、日志对象等,可以使用单例模式。 **实现细节**: 单例模式可以通过构造器私有化、静态内部类等方式实现。 #### 四、多例模式 **定义**: 多例模式...
db.jdbc:jdbc连接池 game:开始游戏 game.message:消息管理者,将客户端的消息传到具体的处理器处理 game.message.handler:消息处理者(功能实现的地方,上接service,下连DAO) net.mina.protocol:自定义通信...
这种模式常用于创建数据库连接池、线程池等共享资源。 #### 五、多例模式(Multiton Pattern) 多例模式是单例模式的一种变体,允许根据不同的参数返回不同的实例。这通常用于需要根据某种条件创建不同实例的情况。...
这种模式常用于日志记录、数据库连接池、线程池等场景,以避免资源浪费和提高性能。 ##### 4. **多例模式【Multiton Pattern】** 多例模式是单例模式的一个变体,它允许一个类有多个实例,并且可以根据某种标识...
- **应用场景**:数据库连接池、日志对象等。 - **多例模式(Multiton Pattern)** - **定义**:与单例模式类似,但允许有多个实例。 - **应用场景**:用户设置等,每个用户可以有自己的配置。 - **抽象工厂模式...
在很多情况下,我们希望整个系统中只有一个特定的对象存在,例如数据库连接池、线程池等。此时,单例模式就能派上用场。 #### 实现 实现一个简单的单例类: ```cpp class Singleton { private: static Singleton...
**案例**:假设需要创建一个数据源管理器的多例,根据不同的数据库名称创建对应的连接池。 ```java import java.util.HashMap; import java.util.Map; public class DataSourceManager { private static final ...
在多线程环境中,我们需要确保某些资源只能被一个线程访问,例如数据库连接池、日志记录器等。 1. **懒汉式单例模式**: ```java public class Singleton { private static Singleton instance; private ...