Java的JDBC数据库连接池实现方法.docx
《Java的JDBC数据库连接池实现方法.docx》由会员分享,可在线阅读,更多相关《Java的JDBC数据库连接池实现方法.docx(13页珍藏版)》请在冰豆网上搜索。
Java的JDBC数据库连接池实现方法
Java的JDBC数据库连接池实现方法
2009-07-1713:
32BBT_softXX空间 我要评论
(1) 字号:
T | T
虽然J2EE程序员一般都有现成的应用服务器所带的JDBC数据库连接池,不过对于开发一般的JavaApplication、Applet或者JSP、velocity时,我们可用的JDBC数据库连接池并不多,并且一般性能都不好。
AD:
Java程序员都很羡慕WindowsADO,只需要newConnection就可以直接从数据库连接池中返回Connection。
并且ADOConnection是线程安全的,多个线程可以共用一个Connection,所以ASP程序一般都把getConnection放在Global.asa文件中,在IIS启动时建立数据库连接。
ADO的Connection和Result都有很好的缓冲,并且很容易使用。
其实我们可以自己写一个JDBC数据库连接池。
写JDBCconnectionpool的注意事项有:
1.有一个简单的函数从连接池中得到一个Connection。
2.close函数必须将connection放回数据库连接池。
3.当数据库连接池中没有空闲的connection,数据库连接池必须能够自动增加connection个数。
4.当数据库连接池中的connection个数在某一个特别的时间变得很大,但是以后很长时间只用其中一小部分,应该可以自动将多余的connection关闭掉。
5.如果可能,应该提供debug信息报告没有关闭的newConnection。
如果要newConnection就可以直接从数据库连接池中返回Connection,可以这样写(Mediatorpattern)(以下代码中使用了中文全角空格):
1.public class EasyConnection implements java.sql.Connection{
2.private Connection m_delegate = null;
3.public EasyConnection(){
4.m_delegate = getConnectionFromPool();
5.}
6. public void close(){
7.putConnectionBackToPool(m_delegate);
8.}
9.public PreparedStatement prepareStatement(String sql) throws SQLException{
10.m_delegate.prepareStatement(sql);
11.}
12.//...... other method
13.}
看来并不难。
不过不建议这种写法,因为应该尽量避免使用JavaInterface,关于JavaInterface的缺点我另外再写文章讨论。
大家关注的是ConnectionPool的实现方法。
下面给出一种实现方法。
1.import java.sql.*;
2.import java.lang.reflect.*;
3.import java.util.*;
4.import java.io.*;
5.
6.public class SimpleConnetionPool {
7.private static LinkedList m_notUsedConnection = new LinkedList();
8.private static HashSet m_usedUsedConnection = new HashSet();
9.private static String m_url = "";
10.private static String m_user = "";
11.private static String m_password = "";
12.static final boolean DEBUG = true;
13.static private long m_lastClearClosedConnection = System.currentTimeMillis();
14.public static long CHECK_CLOSED_CONNECTION_TIME = 4 * 60 * 60 * 1000; //4 hours
15.
16.static {
17.initDriver();
18.}
19.
20.private SimpleConnetionPool() {
21.}
22.
23.private static void initDriver() {
24.Driver driver = null;
25.//load mysql driver
26.try {
27.driver = (Driver) Class.forName("com.mysql.jdbc.Driver").newInstance();
28.installDriver(driver);
29.} catch (Exception e) {
30.}
31.
32.//load postgresql driver
33.try {
34.driver = (Driver) Class.forName("org.postgresql.Driver").newInstance();
35.installDriver(driver);
36.} catch (Exception e) {
37.}
38.}
39.
40.public static void installDriver(Driver driver) {
41.try {
42.DriverManager.registerDriver(driver);
43.} catch (Exception e) {
44.e.printStackTrace();
45.}
46.}
47.
48.
49.public static synchronized Connection getConnection() {
50.clearClosedConnection();
51.while (m_notUsedConnection.size() > 0) {
52.try {
53.ConnectionWrapper wrapper = (ConnectionWrapper) m_notUsedConnection.removeFirst();
54.if (wrapper.connection.isClosed()) {
55.continue;
56.}
57.m_usedUsedConnection.add(wrapper);
58.if (DEBUG) {
59.wrapper.debugInfo = new Throwable("Connection initial statement");
60.}
61.return wrapper.connection;
62.} catch (Exception e) {
63.}
64.}
65.int newCount = getIncreasingConnectionCount();
66.LinkedList list = new LinkedList();
67.ConnectionWrapper wrapper = null;
68.for (int i = 0; i < newCount; i++) {
69.wrapper = getNewConnection();
70.if (wrapper !
= null) {
71.list.add(wrapper);
72.}
73.}
74.if (list.size() == 0) {
75.return null;
76.}
77.wrapper = (ConnectionWrapper) list.removeFirst();
78.m_usedUsedConnection.add(wrapper);
79.
80.m_notUsedConnection.addAll(list);
81.list.clear();
82.
83.return wrapper.connection;
84.}
85.
86.private static ConnectionWrapper getNewConnection() {
87.try {
88.Connection con = DriverManager.getConnection(m_url, m_user, m_password);
89.ConnectionWrapper wrapper = new ConnectionWrapper(con);
90.return wrapper;
91.} catch (Exception e) {
92.e.printStackTrace();
93.}
94.return null;
95.}
96.
97.static synchronized void pushConnectionBackToPool(ConnectionWrapper con) {
98.boolean exist = m_usedUsedConnection.remove(con);
99.if (exist) {
100.m_notUsedConnection.addLast(con);
101.}
102.}
103.
104.public static int close() {
105.int count = 0;
106.
107.Iterator iterator = m_notUsedConnection.iterator();
108.while (iterator.hasNext()) {
109.try {
110.( (ConnectionWrapper) iterator.next()).close();
111.count++;
112.} catch (Exception e) {
113.}
114.}
115.m_notUsedConnection.clear();
116.
117.iterator = m_usedUsedConnection.iterator();
118.while (iterator.hasNext()) {
119.try {
120.ConnectionWrapper wrapper = (ConnectionWrapper) iterator.next();
121.wrapper.close();
122.if (DEBUG) {
123.wrapper.debugInfo.printStackTrace();
124.}
125.count++;
126.} catch (Exception e) {
127.}
128.}
129.m_usedUsedConnection.clear();
130.
131.return count;
132.}
133.
134.private static void clearClosedConnection() {
135.long time = System.currentTimeMillis();
136.//sometimes user change system time,just return
137.if (time < m_lastClearClosedConnection) {
138.time = m_lastClearClosedConnection;
139.return;
140.}
141.//no need check very often
142.if (time - m_lastClearClosedConnection < CHECK_CLOSED_CONNECTION_TIME) {
143.return;
144.}
145.m_lastClearClosedConnection = time;
146.
147.//begin check
148.Iterator iterator = m_notUsedConnection.iterator();
149.while (iterator.hasNext()) {
150.ConnectionWrapper wrapper = (ConnectionWrapper) iterator.next();
151.try {
152.if (wrapper.connection.isClosed()) {
153.iterator.remove();
154.}
155.} catch (Exception e) {
156.iterator.remove();
157.if (DEBUG) {
158.System.out.println("connection is closed, this connection initial StackTrace");
159.wrapper.debugInfo.printStackTrace();
160.}
161.}
162.}
163.
164.//make connection pool size smaller if too big
165.int decrease = getDecreasingConnectionCount();
166.if (m_notUsedConnection.size() < decrease) {
167.return;
168.}
169.
170.while (decrease-- > 0) {
171.ConnectionWrapper wrapper = (ConnectionWrapper) m_notUsedConnection.removeFirst();
172.try {
173.wrapper.connection.close();
174.} catch (Exception e) {
175.}
176.}
177.}
178.
179./**
180. * get increasing connection count, not just add 1 connection
181. * @return count
182. */
183.public static int getIncreasingConnectionCount() {
184.int count = 1;
185.int current = getConnectionCount();
186.count = current / 4;
187.if (count < 1) {
188.count = 1;
189.}
190.return count;
191.}
192.
193./**
194. * get decreasing connection count, not just remove 1 connection
195. * @return count
196. */
197.public static int getDecreasingConnectionCount() {
198.int count = 0;
199.int current = getConnectionCount();
200.if (current < 10) {
201.return 0;
202.}
203.return current / 3;
204.}
205.
206.public synchronized static void printDebugMsg() {
207.printDebugMsg(System.out);
208.}
209.
210.public synchronized static void printDebugMsg(PrintStream out) {
211.if (DEBUG == false) {
212.return;
213.}
214.StringBuffer msg = new StringBuffer();
215.msg.append("debug message in " + SimpleConnetionPool.class.getName());
216.msg.append("\r\n");
217.msg.append("total count is connection pool:
" + getConnectionCount());
218.msg.append("\r\n");
219.msg.append("not used connection count:
" + getNotUsedConnectionCount());
220.msg.append("\r\n");
221.msg.append("used connection, count:
" + getUsedConnectionCount());
222.out.println(msg);
223.Iterator iterator = m_usedUsedConnection.iterator();
224.while (iterator.hasNext()) {
225.ConnectionWrapper wrapper = (ConnectionWrapper) iterator.next();
226.wrapper.debugInfo.printStackTrace(out);
227.}
228.out.println();
229.}
230.
231.public static synchronized int getNotUsedConnectionCount() {
232.return m_notUsedConnection.size();
233.}
234.
235.public static synchronized int getUsedConnectionCount() {
236.return m_usedUsedConnection.size();
237.}
238.
239.public static synchronized int getConnectionCount() {
240.return m_notUsedConnection.size() + m_usedUsedConnection.size();
241.}
242.
243.public static String getUrl() {
244.return m_url;
245.}
246.
247.public static void setUrl(String url) {
248.if (url == null) {
249.return;
250.}
251.m_url = url.trim();
252.}
253.
254.public static String getUser() {
255.return m_user;
256.}
257.
258.public static void setUser(String user) {
259.if (user == null) {
260.return;
261.}
262.m_user = user.trim();
263.}
264.
265.public static String getPassword() {
266.return m_password;
267.}
268.
269.public static void setPassword(String password) {
270.if (password == null) {
271.return;
272.}
273.m_password = password.trim();
274.}
275.
276.}
277.
278.class ConnectionWrapper implements InvocationHandler {
279.private final static String CLOSE_METHOD_NAME = "close";
280.public Connection connection = null;
281.private Connection m_originConnection = null;
282.public long lastAccessTime = System.currentTimeMillis();
283.Throwable debugInfo = new Throwable("Connection initial statement");
284.
285.ConnectionWrapper(Connec