JDBC连接池
java JDBC连接中用到Connection 在每次对数据进行增删查改 都要 开启 、关闭 ,在实例开发项目中 ,浪费了很大的资源 ,以下是之前连接JDBC的案例
package com.jdbc.connection;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
public class jdbcConnection {
private static String driver;
private static String url;
private static String username;
private static String password;
/**
* 静态代码块加载配置文件信息
*/
static {
try {
// 1.通过当前类获取类加载器
ClassLoader classLoader = jdbcConnection.class.getClassLoader();
// 2.通过类加载器的方法获得一个输入流
InputStream is = classLoader.getResourceAsStream("db.properties");
// 3.创建一个properties对象
Properties props = new Properties();
// 4.加载输入流
props.load(is);
// 5.获取相关参数的值
driver = props.getProperty("driver");
url = props.getProperty("url");
username = props.getProperty("username");
password = props.getProperty("password");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 获取连接方法
*
*/
public static Connection getConnection() {
Connection conn = null;
try {
Class.forName(driver);
conn = DriverManager.getConnection(url, username, password);
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
/**
* 释放资源方法
*
* @param conn
* @param pstmt
* @param rs
*/
public static void release(Connection conn, PreparedStatement pstmt, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (pstmt != null) {
try {
pstmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
考虑节省资源 ,可以创建一个connection连接池 ,每次使用connection连接时 ,直接从连接池中取出一个连接,不用时再放回连接池 ,代替之前的关闭连接 。 java提供了javax.sql.DataSource 接口 ,各大连接池厂商直接实现这个接口
常见的连接池有C3P0 DBCP连接池
自定义连接池
在上面代码的基础上添加一个自定义连接池,减少对资源的浪费
1.创建一个类实现javax.jdbc.dataSource 类
2.创建一个 存放多个连接的容器 ,因为需要经常删除 ,查找 。 这里用LinkedList 容器
3.在MyDataSource类中静态代码块中创建多个连接,添加到连接池容器中 (这里面创建连接可以直接使用 com.jdbc.connection包中的jdbcConnection 中的静态方法getConnection)
1 static{
2 for (int i = 0; i < 5; i++) {
3 Connection conn=jdbcConnection.getConnection();
4
5 }
6 }
4.重写Datasource 方法中的 getConnection() 方法 ,
注:在使用pool这个变量之前需要判断pool是否为空 ,若为空需要重新创建
4.在MyDataSource方法中添加 一个 把当前连接归还给连接池的方法
public void addBack(Connection conn){
pool.add(conn);
}
具体操作代码如下
package com.jdbc.dataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.LinkedList;
import java.util.logging.Logger;
import javax.sql.DataSource;
import com.jdbc.connection.jdbcConnection;
public class MyDataSource implements DataSource {
private static LinkedList<Connection> pool=new LinkedList<Connection>();
static{
for (int i = 0; i < 5; i++) {
Connection conn=jdbcConnection.getConnection();
pool.add(conn);
}
}
@Override
public Connection getConnection() throws SQLException {
Connection conn=null;
if (pool.size()==0) {
for (int i = 0; i < 5; i++) {
conn=jdbcConnection.getConnection();
pool.add(conn);
}
}
conn=pool.remove(0);
return conn;
}
public void addBack(Connection conn){
pool.add(conn);
}
@Override
public PrintWriter getLogWriter() throws SQLException {
return null;
}
@Override
public int getLoginTimeout() throws SQLException {
// TODO Auto-generated method stub
return 0;
}
@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
// TODO Auto-generated method stub
return null;
}
@Override
public void setLogWriter(PrintWriter arg0) throws SQLException {
// TODO Auto-generated method stub
}
@Override
public void setLoginTimeout(int arg0) throws SQLException {
// TODO Auto-generated method stub
}
@Override
public boolean isWrapperFor(Class<?> arg0) throws SQLException {
// TODO Auto-generated method stub
return false;
}
@Override
public <T> T unwrap(Class<T> arg0) throws SQLException {
// TODO Auto-generated method stub
return null;
}
@Override
public Connection getConnection(String arg0, String arg1)
throws SQLException {
return null;
}
}
连接池测试类
1 package com.jdbc.Util;
2
3 import java.sql.Connection;
4 import java.sql.PreparedStatement;
5 import java.sql.SQLException;
6
7 import org.junit.Test;
8
9 import com.jdbc.dataSource.MyDataSource;
10
11 public class JdbcTest {
12
13 @Test
14 public void test1(){
15 Connection conn=null;
16 PreparedStatement pstm=null;
17 MyDataSource myDataSource=new MyDataSource();
18 try {
19 conn=myDataSource.getConnection();
20
21 } catch (SQLException e) {
22 e.printStackTrace();
23 }
24
25 }
26 }
自定义连接池:方法增强
装饰者模式
- 创建类B,并实现接口A
- 提供类B的构造方法,参数类型为A,用于接收A接口的其他实现类(c)
- 给类B添加类型为A的成员变量,用于存放A接口的其他实现类
- 增加需要的方法
- 实现不需要增强的方法,方法体 重点调用成员变量存放的其他实现类对应的方法
翻译过来就是创建类 MyConnection 实现Connection接口
提供MyConnection的构造方法,参数类型为Connection的、 MyDataSource 类中的连接池对象list
。。。等
1 package com.jdbc.dataSource;
2
3 import java.sql.Array;
4 import java.sql.Blob;
5 import java.sql.CallableStatement;
6 import java.sql.Clob;
7 import java.sql.Connection;
8 import java.sql.DatabaseMetaData;
9 import java.sql.NClob;
10 import java.sql.PreparedStatement;
11 import java.sql.SQLClientInfoException;
12 import java.sql.SQLException;
13 import java.sql.SQLWarning;
14 import java.sql.SQLXML;
15 import java.sql.Savepoint;
16 import java.sql.Statement;
17 import java.sql.Struct;
18 import java.util.LinkedList;
19 import java.util.Map;
20 import java.util.Properties;
21 import java.util.concurrent.Executor;
22
23 public class MyConnection implements Connection {
24 private Connection conn;
25 private LinkedList<Connection> pool;
26 public MyConnection(Connection conn ,LinkedList<Connection> pool) {
27 this.pool=pool;
28 this.conn = conn;
29 }
30 @Override
31 public void close() throws SQLException {
32 pool.add(conn);
33 }
34 @Override
35 public boolean isWrapperFor(Class<?> arg0) throws SQLException {
36 // TODO Auto-generated method stub
37 return false;
38 }
39
40 @Override
41 public <T> T unwrap(Class<T> arg0) throws SQLException {
42 // TODO Auto-generated method stub
43 return null;
44 }
45
46 @Override
47 public void abort(Executor executor) throws SQLException {
48 // TODO Auto-generated method stub
49
50 }
51
52 @Override
53 public void clearWarnings() throws SQLException {
54 // TODO Auto-generated method stub
55
56 }
57
58
59
60 @Override
61 public void commit() throws SQLException {
62 // TODO Auto-generated method stub
63
64 }
65
66 @Override
67 public Array createArrayOf(String typeName, Object[] elements)
68 throws SQLException {
69 // TODO Auto-generated method stub
70 return null;
71 }
72
73 @Override
74 public Blob createBlob() throws SQLException {
75 // TODO Auto-generated method stub
76 return null;
77 }
78
79 @Override
80 public Clob createClob() throws SQLException {
81 // TODO Auto-generated method stub
82 return null;
83 }
84
85 @Override
86 public NClob createNClob() throws SQLException {
87 // TODO Auto-generated method stub
88 return null;
89 }
90
91 @Override
92 public SQLXML createSQLXML() throws SQLException {
93 // TODO Auto-generated method stub
94 return null;
95 }
96
97 @Override
98 public Statement createStatement() throws SQLException {
99 // TODO Auto-generated method stub
100 return null;
101 }
102
103 @Override
104 public Statement createStatement(int resultSetType, int resultSetConcurrency)
105 throws SQLException {
106 // TODO Auto-generated method stub
107 return null;
108 }
109
110 @Override
111 public Statement createStatement(int resultSetType,
112 int resultSetConcurrency, int resultSetHoldability)
113 throws SQLException {
114 // TODO Auto-generated method stub
115 return null;
116 }
117
118 @Override
119 public Struct createStruct(String typeName, Object[] attributes)
120 throws SQLException {
121 // TODO Auto-generated method stub
122 return null;
123 }
124
125 @Override
126 public boolean getAutoCommit() throws SQLException {
127 // TODO Auto-generated method stub
128 return false;
129 }
130
131 @Override
132 public String getCatalog() throws SQLException {
133 // TODO Auto-generated method stub
134 return null;
135 }
136
137 @Override
138 public Properties getClientInfo() throws SQLException {
139 // TODO Auto-generated method stub
140 return null;
141 }
142
143 @Override
144 public String getClientInfo(String name) throws SQLException {
145 // TODO Auto-generated method stub
146 return null;
147 }
148
149 @Override
150 public int getHoldability() throws SQLException {
151 // TODO Auto-generated method stub
152 return 0;
153 }
154
155 @Override
156 public DatabaseMetaData getMetaData() throws SQLException {
157 // TODO Auto-generated method stub
158 return null;
159 }
160
161 @Override
162 public int getNetworkTimeout() throws SQLException {
163 // TODO Auto-generated method stub
164 return 0;
165 }
166
167 @Override
168 public String getSchema() throws SQLException {
169 // TODO Auto-generated method stub
170 return null;
171 }
172
173 @Override
174 public int getTransactionIsolation() throws SQLException {
175 // TODO Auto-generated method stub
176 return 0;
177 }
178
179 @Override
180 public Map<String, Class<?>> getTypeMap() throws SQLException {
181 // TODO Auto-generated method stub
182 return null;
183 }
184
185 @Override
186 public SQLWarning getWarnings() throws SQLException {
187 // TODO Auto-generated method stub
188 return null;
189 }
190
191 @Override
192 public boolean isClosed() throws SQLException {
193 // TODO Auto-generated method stub
194 return false;
195 }
196
197 @Override
198 public boolean isReadOnly() throws SQLException {
199 // TODO Auto-generated method stub
200 return false;
201 }
202
203 @Override
204 public boolean isValid(int timeout) throws SQLException {
205 // TODO Auto-generated method stub
206 return false;
207 }
208
209 @Override
210 public String nativeSQL(String sql) throws SQLException {
211 // TODO Auto-generated method stub
212 return null;
213 }
214
215 @Override
216 public CallableStatement prepareCall(String sql) throws SQLException {
217 // TODO Auto-generated method stub
218 return null;
219 }
220
221 @Override
222 public CallableStatement prepareCall(String sql, int resultSetType,
223 int resultSetConcurrency) throws SQLException {
224 // TODO Auto-generated method stub
225 return null;
226 }
227
228 @Override
229 public CallableStatement prepareCall(String sql, int resultSetType,
230 int resultSetConcurrency, int resultSetHoldability)
231 throws SQLException {
232 // TODO Auto-generated method stub
233 return null;
234 }
235
236 @Override
237 public PreparedStatement prepareStatement(String sql) throws SQLException {
238 // TODO Auto-generated method stub
239 return null;
240 }
241
242 @Override
243 public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
244 throws SQLException {
245 // TODO Auto-generated method stub
246 return null;
247 }
248
249 @Override
250 public PreparedStatement prepareStatement(String sql, int[] columnIndexes)
251 throws SQLException {
252 // TODO Auto-generated method stub
253 return null;
254 }
255
256 @Override
257 public PreparedStatement prepareStatement(String sql, String[] columnNames)
258 throws SQLException {
259 // TODO Auto-generated method stub
260 return null;
261 }
262
263 @Override
264 public PreparedStatement prepareStatement(String sql, int resultSetType,
265 int resultSetConcurrency) throws SQLException {
266 // TODO Auto-generated method stub
267 return null;
268 }
269
270 @Override
271 public PreparedStatement prepareStatement(String sql, int resultSetType,
272 int resultSetConcurrency, int resultSetHoldability)
273 throws SQLException {
274 // TODO Auto-generated method stub
275 return null;
276 }
277
278 @Override
279 public void releaseSavepoint(Savepoint savepoint) throws SQLException {
280 // TODO Auto-generated method stub
281
282 }
283
284 @Override
285 public void rollback() throws SQLException {
286 // TODO Auto-generated method stub
287
288 }
289
290 @Override
291 public void rollback(Savepoint savepoint) throws SQLException {
292 // TODO Auto-generated method stub
293
294 }
295
296 @Override
297 public void setAutoCommit(boolean autoCommit) throws SQLException {
298 // TODO Auto-generated method stub
299
300 }
301
302 @Override
303 public void setCatalog(String catalog) throws SQLException {
304 // TODO Auto-generated method stub
305
306 }
307
308 @Override
309 public void setClientInfo(Properties properties)
310 throws SQLClientInfoException {
311 // TODO Auto-generated method stub
312
313 }
314
315 @Override
316 public void setClientInfo(String name, String value)
317 throws SQLClientInfoException {
318 // TODO Auto-generated method stub
319
320 }
321
322 @Override
323 public void setHoldability(int holdability) throws SQLException {
324 // TODO Auto-generated method stub
325
326 }
327
328 @Override
329 public void setNetworkTimeout(Executor executor, int milliseconds)
330 throws SQLException {
331 // TODO Auto-generated method stub
332
333 }
334
335 @Override
336 public void setReadOnly(boolean readOnly) throws SQLException {
337 // TODO Auto-generated method stub
338
339 }
340
341 @Override
342 public Savepoint setSavepoint() throws SQLException {
343 // TODO Auto-generated method stub
344 return null;
345 }
346
347 @Override
348 public Savepoint setSavepoint(String name) throws SQLException {
349 // TODO Auto-generated method stub
350 return null;
351 }
352
353 @Override
354 public void setSchema(String schema) throws SQLException {
355 // TODO Auto-generated method stub
356
357 }
358
359 @Override
360 public void setTransactionIsolation(int level) throws SQLException {
361 // TODO Auto-generated method stub
362
363 }
364
365 @Override
366 public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
367 // TODO Auto-generated method stub
368
369 }
370
371
372 }
更改后的myDataSource类为
1 package com.jdbc.dataSource;
2
3 import java.io.PrintWriter;
4 import java.sql.Connection;
5 import java.sql.SQLException;
6 import java.sql.SQLFeatureNotSupportedException;
7 import java.util.LinkedList;
8 import java.util.logging.Logger;
9
10 import javax.sql.DataSource;
11
12 import com.jdbc.connection.jdbcConnection;
13
14 public class MyDataSource1 implements DataSource{
15 private static LinkedList<Connection> pool=new LinkedList<Connection>();
16 static{
17 for (int i = 0; i < 5; i++) {
18 Connection conn=jdbcConnection.getConnection();
19 pool.add(conn);
20 }
21 }
22 @Override
23 public Connection getConnection() throws SQLException {
24 if (pool.size()==0) {
25 for (int i = 0; i < 5; i++) {
26 Connection conn=jdbcConnection.getConnection();
27 //MyConnection 类实现了Connection接口
28 //将创建的连接用装饰者类包装
29 MyConnection myConnection=new MyConnection(conn, pool);
30 //pool.add(conn);
31 pool.add(myConnection);//添加被装饰后的connection对象
32 }
33 }
34 Connection conn=pool.remove(0);
35 return conn;
36 }
37
38 @Override
39 public PrintWriter getLogWriter() throws SQLException {
40
41 return null;
42 }
43
44 @Override
45 public int getLoginTimeout() throws SQLException {
46 // TODO Auto-generated method stub
47 return 0;
48 }
49
50 @Override
51 public Logger getParentLogger() throws SQLFeatureNotSupportedException {
52 // TODO Auto-generated method stub
53 return null;
54 }
55
56 @Override
57 public void setLogWriter(PrintWriter arg0) throws SQLException {
58 // TODO Auto-generated method stub
59
60 }
61
62 @Override
63 public void setLoginTimeout(int arg0) throws SQLException {
64 // TODO Auto-generated method stub
65
66 }
67
68 @Override
69 public boolean isWrapperFor(Class<?> iface) throws SQLException {
70 // TODO Auto-generated method stub
71 return false;
72 }
73
74 @Override
75 public <T> T unwrap(Class<T> iface) throws SQLException {
76 // TODO Auto-generated method stub
77 return null;
78 }
79
80
81
82 @Override
83 public Connection getConnection(String username, String password)
84 throws SQLException {
85 // TODO Auto-generated method stub
86 return null;
87 }
88
89
90
91 }
测试
package com.study.jdbc.test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import org.junit.Test;
import com.study.jdbc.Utils.JDBCUtils_V3;
import com.study.jdbc.dataSource.MyDataSource;
import com.study.jdbc.dataSource.MyDataSource1;
public class TestMyDataSource {
/*
* 添加用户
* 使用改造过的connection
*
*/
@Test
public void dataTestAddUser1(){
Connection conn=null;
PreparedStatement pstm=null;
MyDataSource1 dataSource=new MyDataSource1();
try {
conn=dataSource.getConnection();
System.out.println(conn);
String sql="insert into user values(10,?,?)";
pstm=conn.prepareStatement(sql);
pstm.setString(1,"吕布1");
pstm.setString(2,"点错1");
int rows =pstm.executeUpdate();
if (rows>0) {
System.out.println("ok");
}else {
System.out.println("no");
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
//release中conn.close()方法已经被装饰
JDBCUtils_V3.release(conn, pstm, null);
}
}
}
需要注意的是:MyConection 实现Connection接口时重新了Connection所有的方法,在使用 被MyConnection类修饰的Connecting连接的某些方法要注意需要重写MyConnection类中的这些方法
比如:当使用prepareStatement(sql); 时 要注意MyConnection中的prepareStatement(String sql)方法
MyConnection 在未处理之前的prepareStatement(String sql)方法如下图所示
不重写直接使用 返回的结果永远是null ,重写后代码:
1 @Override
2 public PreparedStatement prepareStatement(String sql) throws SQLException {
3 // TODO Auto-generated method stub
4 return conn.prepareStatement(sql);
5 }