JDBC学习笔记(18):通过代理模式来保持用户关闭连接的习惯
在前面的JdbcUtils包中,在关闭连接的时候使用了conn.close()方法,如果关闭了连接,那么放回连接池中的连接就成为无效的连接,为了规范用户关闭连接的习惯,使用代理模式来将连接放回连接池而又不改变用户的程序:
1 package com.xxyh.jdbc; 2 import java.sql.Connection; 3 import java.sql.ResultSet; 4 import java.sql.SQLException; 5 import java.sql.Statement; 6 import com.xxyh.jdbc.datasource.MyDataSource2; 7 public class JdbcUtils { 8 private static MyDataSource2 myDataSource = null; 9 10 private JdbcUtils() { 11 } 12 13 static { 14 try { 15 // 将注册驱动放在静态代码块中只需执行一次 16 Class.forName("com.mysql.jdbc.Driver"); 17 myDataSource = new MyDataSource2(); 18 } catch(ClassNotFoundException e) { 19 throw new ExceptionInInitializerError(e); 20 } 21 } 22 23 public static Connection getConnection() throws SQLException { 24 // return DriverManager.getConnection(url, user, password); 25 // 当需要连接的时候,不再创建,而是从连接池中获取 26 return myDataSource.getConnection(); 27 } 28 29 public static void close(ResultSet rs, Statement stmt, Connection conn) { 30 try { 31 if (rs != null) { 32 rs.close(); 33 } 34 } catch (SQLException e) { 35 e.printStackTrace(); 36 } finally { 37 try { 38 if (stmt != null) { 39 stmt.close(); 40 } 41 } catch (SQLException e) { 42 e.printStackTrace(); 43 } finally { 44 if (conn != null) { 45 try { 46 conn.close(); ///////按照常用情形关闭连接 47 // 将连接放回连接池,而不是关闭连接 48 // myDataSource.free(conn); 49 } catch (Exception e) { 50 e.printStackTrace(); 51 } 52 } 53 } 54 } 55 } 56 }
创建自己的连接方式,实现java.sql.Connection接口,截取部分代码:
1 package com.xxyh.jdbc.datasource; 2 import java.sql.Array; 3 import java.sql.Blob; 4 import java.sql.CallableStatement; 5 import java.sql.Clob; 6 import java.sql.Connection; 7 import java.sql.DatabaseMetaData; 8 import java.sql.NClob; 9 import java.sql.PreparedStatement; 10 import java.sql.SQLClientInfoException; 11 import java.sql.SQLException; 12 import java.sql.SQLWarning; 13 import java.sql.SQLXML; 14 import java.sql.Savepoint; 15 import java.sql.Statement; 16 import java.sql.Struct; 17 import java.util.Map; 18 import java.util.Properties; 19 import java.util.concurrent.Executor; 20 public class MyConnection implements Connection{ 21 22 private Connection realConnetion; // 真正的数据库连接,可能来源于MySQL、Oracle、DB2…… 23 private MyDataSource2 dataSource; 24 25 MyConnection(Connection connection, MyDataSource2 dataSource) { 26 this.realConnetion = connection; 27 this.dataSource = dataSource; 28 } 29 30 @Override 31 public void close() throws SQLException { 32 this.dataSource.connectionsPool.addLast(this); 33 } 34 35 @Override 36 public void commit() throws SQLException { 37 // TODO Auto-generated method stub 38 this.realConnetion.commit(); 39 }
1 package com.xxyh.jdbc.datasource; 2 import java.sql.Connection; 3 import java.sql.DriverManager; 4 import java.sql.SQLException; 5 import java.util.LinkedList; 6 public class MyDataSource2 { 7 private static String url = "jdbc:mysql://localhost:3306/jdbc?generateSimpleParameterMetadata=true"; 8 private static String user = "root"; 9 private static String password = "1234"; 10 11 private static int initCount = 5; // 初始连接数 12 private static int maxCount = 10; // 最大连接数 13 private int currentCount = 0; // 当前连接数 14 15 ////////包内可见 16 LinkedList<Connection> connectionsPool = new LinkedList<>(); 17 18 public MyDataSource2() { 19 try { 20 // 创建 5 个连接 21 for (int i = 0; i < initCount; i++) { 22 this.connectionsPool.addLast(this.createConnection()); 23 this.currentCount++; 24 } 25 } catch (SQLException e) { 26 throw new ExceptionInInitializerError(e); 27 } 28 } 29 30 private Connection createConnection() throws SQLException { 31 Connection realConn = DriverManager.getConnection(url, user, password); 32 MyConnection myConnection = new MyConnection(realConn, this); 33 return myConnection; 34 } 35 36 public void free(Connection conn) { 37 // 释放一个连接,将它放回连接池 38 this.connectionsPool.addLast(conn); 39 } 40 41 public Connection getConnection() throws SQLException { 42 // 从连接池中获取一个连接 43 synchronized(connectionsPool) { 44 if (this.connectionsPool.size() > 0) 45 return this.connectionsPool.removeFirst(); 46 47 // 如果连接池中没有连接且当前连接小于最大连接,则创建一个连接 48 if (this.currentCount < maxCount) { 49 this.currentCount++; 50 return this.createConnection(); 51 } 52 53 throw new SQLException("已没有连接"); 54 } 55 } 56 }
测试创建的连接:
1 package com.xxyh.jdbc; 2 import java.sql.Connection; 3 import java.sql.DriverManager; 4 import java.sql.ResultSet; 5 import java.sql.SQLException; 6 import java.sql.Statement; 7 public class Base { 8 public static void main(String[] args) throws ClassNotFoundException, SQLException { 9 10 for (int i = 0; i < 5; i++) { 11 Connection conn = JdbcUtils.getConnection(); 12 System.out.println(conn); 13 JdbcUtils.close(null, null, conn); 14 } 15 } 16 }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。