JDBC连接池
java JDBC连接中用到Connection 在每次对数据进行增删查改 都要 开启 、关闭 ,在实例开发项目中 ,浪费了很大的资源 ,以下是之前连接JDBC的案例
packagecom.jdbc.connection;importjava.io.IOException;importjava.io.InputStream;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.PreparedStatement;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.util.Properties;public classjdbcConnection {private staticString driver;private staticString url;private staticString username;private staticString password;/*** 静态代码块加载配置文件信息*/
static{try{//1.通过当前类获取类加载器
ClassLoader classLoader = jdbcConnection.class.getClassLoader();//2.通过类加载器的方法获得一个输入流
InputStream is = classLoader.getResourceAsStream("db.properties");//3.创建一个properties对象
Properties props = newProperties();//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 staticConnection getConnection() {
Connection conn= null;try{
Class.forName(driver);
conn=DriverManager.getConnection(url, username, password);
}catch(Exception e) {
e.printStackTrace();
}returnconn;
}/*** 释放资源方法
*
*@paramconn
*@parampstmt
*@paramrs*/
public static voidrelease(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 voidaddBack(Connection conn){
pool.add(conn);
}
具体操作代码如下
packagecom.jdbc.dataSource;importjava.io.PrintWriter;importjava.sql.Connection;importjava.sql.SQLException;importjava.sql.SQLFeatureNotSupportedException;importjava.util.LinkedList;importjava.util.logging.Logger;importjavax.sql.DataSource;importcom.jdbc.connection.jdbcConnection;public class MyDataSource implementsDataSource {private static LinkedList pool=new LinkedList();static{for (int i = 0; i < 5; i++) {
Connection conn=jdbcConnection.getConnection();
pool.add(conn);
}
}
@Overridepublic Connection getConnection() throwsSQLException {
Connection conn=null;if (pool.size()==0) {for (int i = 0; i < 5; i++) {
conn=jdbcConnection.getConnection();
pool.add(conn);
}
}
conn=pool.remove(0);returnconn;
}public voidaddBack(Connection conn){
pool.add(conn);
}
@Overridepublic PrintWriter getLogWriter() throwsSQLException {return null;
}
@Overridepublic int getLoginTimeout() throwsSQLException {//TODO Auto-generated method stub
return 0;
}
@Overridepublic Logger getParentLogger() throwsSQLFeatureNotSupportedException {//TODO Auto-generated method stub
return null;
}
@Overridepublic void setLogWriter(PrintWriter arg0) throwsSQLException {//TODO Auto-generated method stub
}
@Overridepublic void setLoginTimeout(int arg0) throwsSQLException {//TODO Auto-generated method stub
}
@Overridepublic boolean isWrapperFor(Class> arg0) throwsSQLException {//TODO Auto-generated method stub
return false;
}
@Overridepublic T unwrap(Class arg0) throwsSQLException {//TODO Auto-generated method stub
return null;
}
@OverridepublicConnection getConnection(String arg0, String arg1)throwsSQLException {return null;
}
}
连接池测试类
1 packagecom.jdbc.Util;2
3 importjava.sql.Connection;4 importjava.sql.PreparedStatement;5 importjava.sql.SQLException;6
7 importorg.junit.Test;8
9 importcom.jdbc.dataSource.MyDataSource;10
11 public classJdbcTest {12
13 @Test14 public voidtest1(){15 Connection conn=null;16 PreparedStatement pstm=null;17 MyDataSource myDataSource=newMyDataSource();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 packagecom.jdbc.dataSource;2
3 importjava.sql.Array;4 importjava.sql.Blob;5 importjava.sql.CallableStatement;6 importjava.sql.Clob;7 importjava.sql.Connection;8 importjava.sql.DatabaseMetaData;9 importjava.sql.NClob;10 importjava.sql.PreparedStatement;11 importjava.sql.SQLClientInfoException;12 importjava.sql.SQLException;13 importjava.sql.SQLWarning;14 importjava.sql.SQLXML;15 importjava.sql.Savepoint;16 importjava.sql.Statement;17 importjava.sql.Struct;18 importjava.util.LinkedList;19 importjava.util.Map;20 importjava.util.Properties;21 importjava.util.concurrent.Executor;22
23 public class MyConnection implementsConnection {24 privateConnection conn;25 private LinkedListpool;26 public MyConnection(Connection conn ,LinkedListpool) {27 this.pool=pool;28 this.conn =conn;29 }30 @Override31 public void close() throwsSQLException {32 pool.add(conn);33 }34 @Override35 public boolean isWrapperFor(Class> arg0) throwsSQLException {36 //TODO Auto-generated method stub
37 return false;38 }39
40 @Override41 public T unwrap(Class arg0) throwsSQLException {42 //TODO Auto-generated method stub
43 return null;44 }45
46 @Override47 public void abort(Executor executor) throwsSQLException {48 //TODO Auto-generated method stub
49
50 }51
52 @Override53 public void clearWarnings() throwsSQLException {54 //TODO Auto-generated method stub
55
56 }57
58
59
60 @Override61 public void commit() throwsSQLException {62 //TODO Auto-generated method stub
63
64 }65
66 @Override67 publicArray createArrayOf(String typeName, Object[] elements)68 throwsSQLException {69 //TODO Auto-generated method stub
70 return null;71 }72
73 @Override74 public Blob createBlob() throwsSQLException {75 //TODO Auto-generated method stub
76 return null;77 }78
79 @Override80 public Clob createClob() throwsSQLException {81 //TODO Auto-generated method stub
82 return null;83 }84
85 @Override86 public NClob createNClob() throwsSQLException {87 //TODO Auto-generated method stub
88 return null;89 }90
91 @Override92 public SQLXML createSQLXML() throwsSQLException {93 //TODO Auto-generated method stub
94 return null;95 }96
97 @Override98 public Statement createStatement() throwsSQLException {99 //TODO Auto-generated method stub
100 return null;101 }102
103 @Override104 public Statement createStatement(int resultSetType, intresultSetConcurrency)105 throwsSQLException {106 //TODO Auto-generated method stub
107 return null;108 }109
110 @Override111 public Statement createStatement(intresultSetType,112 int resultSetConcurrency, intresultSetHoldability)113 throwsSQLException {114 //TODO Auto-generated method stub
115 return null;116 }117
118 @Override119 publicStruct createStruct(String typeName, Object[] attributes)120 throwsSQLException {121 //TODO Auto-generated method stub
122 return null;123 }124
125 @Override126 public boolean getAutoCommit() throwsSQLException {127 //TODO Auto-generated method stub
128 return false;129 }130
131 @Override132 public String getCatalog() throwsSQLException {133 //TODO Auto-generated method stub
134 return null;135 }136
137 @Override138 public Properties getClientInfo() throwsSQLException {139 //TODO Auto-generated method stub
140 return null;141 }142
143 @Override144 public String getClientInfo(String name) throwsSQLException {145 //TODO Auto-generated method stub
146 return null;147 }148
149 @Override150 public int getHoldability() throwsSQLException {151 //TODO Auto-generated method stub
152 return 0;153 }154
155 @Override156 public DatabaseMetaData getMetaData() throwsSQLException {157 //TODO Auto-generated method stub
158 return null;159 }160
161 @Override162 public int getNetworkTimeout() throwsSQLException {163 //TODO Auto-generated method stub
164 return 0;165 }166
167 @Override168 public String getSchema() throwsSQLException {169 //TODO Auto-generated method stub
170 return null;171 }172
173 @Override174 public int getTransactionIsolation() throwsSQLException {175 //TODO Auto-generated method stub
176 return 0;177 }178
179 @Override180 public Map> getTypeMap() throwsSQLException {181 //TODO Auto-generated method stub
182 return null;183 }184
185 @Override186 public SQLWarning getWarnings() throwsSQLException {187 //TODO Auto-generated method stub
188 return null;189 }190
191 @Override192 public boolean isClosed() throwsSQLException {193 //TODO Auto-generated method stub
194 return false;195 }196
197 @Override198 public boolean isReadOnly() throwsSQLException {199 //TODO Auto-generated method stub
200 return false;201 }202
203 @Override204 public boolean isValid(int timeout) throwsSQLException {205 //TODO Auto-generated method stub
206 return false;207 }208
209 @Override210 public String nativeSQL(String sql) throwsSQLException {211 //TODO Auto-generated method stub
212 return null;213 }214
215 @Override216 public CallableStatement prepareCall(String sql) throwsSQLException {217 //TODO Auto-generated method stub
218 return null;219 }220
221 @Override222 public CallableStatement prepareCall(String sql, intresultSetType,223 int resultSetConcurrency) throwsSQLException {224 //TODO Auto-generated method stub
225 return null;226 }227
228 @Override229 public CallableStatement prepareCall(String sql, intresultSetType,230 int resultSetConcurrency, intresultSetHoldability)231 throwsSQLException {232 //TODO Auto-generated method stub
233 return null;234 }235
236 @Override237 public PreparedStatement prepareStatement(String sql) throwsSQLException {238 //TODO Auto-generated method stub
239 return null;240 }241
242 @Override243 public PreparedStatement prepareStatement(String sql, intautoGeneratedKeys)244 throwsSQLException {245 //TODO Auto-generated method stub
246 return null;247 }248
249 @Override250 public PreparedStatement prepareStatement(String sql, int[] columnIndexes)251 throwsSQLException {252 //TODO Auto-generated method stub
253 return null;254 }255
256 @Override257 publicPreparedStatement prepareStatement(String sql, String[] columnNames)258 throwsSQLException {259 //TODO Auto-generated method stub
260 return null;261 }262
263 @Override264 public PreparedStatement prepareStatement(String sql, intresultSetType,265 int resultSetConcurrency) throwsSQLException {266 //TODO Auto-generated method stub
267 return null;268 }269
270 @Override271 public PreparedStatement prepareStatement(String sql, intresultSetType,272 int resultSetConcurrency, intresultSetHoldability)273 throwsSQLException {274 //TODO Auto-generated method stub
275 return null;276 }277
278 @Override279 public void releaseSavepoint(Savepoint savepoint) throwsSQLException {280 //TODO Auto-generated method stub
281
282 }283
284 @Override285 public void rollback() throwsSQLException {286 //TODO Auto-generated method stub
287
288 }289
290 @Override291 public void rollback(Savepoint savepoint) throwsSQLException {292 //TODO Auto-generated method stub
293
294 }295
296 @Override297 public void setAutoCommit(boolean autoCommit) throwsSQLException {298 //TODO Auto-generated method stub
299
300 }301
302 @Override303 public void setCatalog(String catalog) throwsSQLException {304 //TODO Auto-generated method stub
305
306 }307
308 @Override309 public voidsetClientInfo(Properties properties)310 throwsSQLClientInfoException {311 //TODO Auto-generated method stub
312
313 }314
315 @Override316 public voidsetClientInfo(String name, String value)317 throwsSQLClientInfoException {318 //TODO Auto-generated method stub
319
320 }321
322 @Override323 public void setHoldability(int holdability) throwsSQLException {324 //TODO Auto-generated method stub
325
326 }327
328 @Override329 public void setNetworkTimeout(Executor executor, intmilliseconds)330 throwsSQLException {331 //TODO Auto-generated method stub
332
333 }334
335 @Override336 public void setReadOnly(boolean readOnly) throwsSQLException {337 //TODO Auto-generated method stub
338
339 }340
341 @Override342 public Savepoint setSavepoint() throwsSQLException {343 //TODO Auto-generated method stub
344 return null;345 }346
347 @Override348 public Savepoint setSavepoint(String name) throwsSQLException {349 //TODO Auto-generated method stub
350 return null;351 }352
353 @Override354 public void setSchema(String schema) throwsSQLException {355 //TODO Auto-generated method stub
356
357 }358
359 @Override360 public void setTransactionIsolation(int level) throwsSQLException {361 //TODO Auto-generated method stub
362
363 }364
365 @Override366 public void setTypeMap(Map> map) throwsSQLException {367 //TODO Auto-generated method stub
368
369 }370
371
372 }
更改后的myDataSource类为
1 packagecom.jdbc.dataSource;2
3 importjava.io.PrintWriter;4 importjava.sql.Connection;5 importjava.sql.SQLException;6 importjava.sql.SQLFeatureNotSupportedException;7 importjava.util.LinkedList;8 importjava.util.logging.Logger;9
10 importjavax.sql.DataSource;11
12 importcom.jdbc.connection.jdbcConnection;13
14 public class MyDataSource1 implementsDataSource{15 private static LinkedList pool=new LinkedList();16 static{17 for (int i = 0; i < 5; i++) {18 Connection conn=jdbcConnection.getConnection();19 pool.add(conn);20 }21 }22 @Override23 public Connection getConnection() throwsSQLException {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=newMyConnection(conn, pool);30 //pool.add(conn);
31 pool.add(myConnection);//添加被装饰后的connection对象
32 }33 }34 Connection conn=pool.remove(0);35 returnconn;36 }37
38 @Override39 public PrintWriter getLogWriter() throwsSQLException {40
41 return null;42 }43
44 @Override45 public int getLoginTimeout() throwsSQLException {46 //TODO Auto-generated method stub
47 return 0;48 }49
50 @Override51 public Logger getParentLogger() throwsSQLFeatureNotSupportedException {52 //TODO Auto-generated method stub
53 return null;54 }55
56 @Override57 public void setLogWriter(PrintWriter arg0) throwsSQLException {58 //TODO Auto-generated method stub
59
60 }61
62 @Override63 public void setLoginTimeout(int arg0) throwsSQLException {64 //TODO Auto-generated method stub
65
66 }67
68 @Override69 public boolean isWrapperFor(Class> iface) throwsSQLException {70 //TODO Auto-generated method stub
71 return false;72 }73
74 @Override75 public T unwrap(Class iface) throwsSQLException {76 //TODO Auto-generated method stub
77 return null;78 }79
80
81
82 @Override83 publicConnection getConnection(String username, String password)84 throwsSQLException {85 //TODO Auto-generated method stub
86 return null;87 }88
89
90
91 }
测试
packagecom.study.jdbc.test;importjava.sql.Connection;importjava.sql.PreparedStatement;importjava.sql.SQLException;importorg.junit.Test;importcom.study.jdbc.Utils.JDBCUtils_V3;importcom.study.jdbc.dataSource.MyDataSource;importcom.study.jdbc.dataSource.MyDataSource1;public classTestMyDataSource {/** 添加用户
* 使用改造过的connection
**/@Testpublic voiddataTestAddUser1(){
Connection conn=null;
PreparedStatement pstm=null;
MyDataSource1 dataSource=newMyDataSource1();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 @Override2 public PreparedStatement prepareStatement(String sql) throwsSQLException {3 //TODO Auto-generated method stub
4 returnconn.prepareStatement(sql);5 }