当前位置:网站首页>连接池-归还连接详解(下)
连接池-归还连接详解(下)
2022-07-28 22:03:00 【汤键.】
目录
适配器设计模式归还数据库连接的思想
- 我们可以提供一个适配器类,实现Connection接口,将所有方法进行实现(除了close方法)
- 自定义连接类只需要继承这个适配器类,重写需要改进的close()方法即可
适配器设计模式归还数据库连接的实现步骤
- 1.定义一个适配器类,实现Connection接口
- 2.定义Connection连接对象的成员变量
- 3.通过有参构造方法完成对成员变量的赋值
- 4.重写所有方法(除了close),调用mysql驱动包的连接对象即可
- 5.定义一个连接类,继承适配器类
- 6.定义Connection连接对象和连接池容器对象的成员变量,并通过有参构造进行赋值
- 7.重写close()方法,完成归还连接
- 8.在自定义连接池中,将获取的连接对象通过自定义连接对象进行包装
适配器设计模式归还数据库连接存在的问题
- 自定义连接虽然很简洁了,但适配器类还是我们自己编写的,也比较麻烦
适配器设计模式归还数据库连接的实例演示
package demo02.myDataSourse; import java.sql.*; import java.util.Map; import java.util.Properties; import java.util.concurrent.Executor; //1.定义一个适配器类,实现Connection接口 public abstract class myAdapter implements Connection{ //2.定义连接对象的成员变量 private Connection con; //3.通过有参构造为变量赋值 public myAdapter(Connection con) { this.con = con; } //4.重写所有的抽象方法(除了close) @Override public Statement createStatement() throws SQLException { return con.createStatement(); } @Override public PreparedStatement prepareStatement(String sql) throws SQLException { return con.prepareStatement(sql); } @Override public CallableStatement prepareCall(String sql) throws SQLException { return con.prepareCall(sql); } @Override public String nativeSQL(String sql) throws SQLException { return con.nativeSQL(sql); } @Override public void setAutoCommit(boolean autoCommit) throws SQLException { con.setAutoCommit(autoCommit); } @Override public boolean getAutoCommit() throws SQLException { return con.getAutoCommit(); } @Override public void commit() throws SQLException { con.commit(); } @Override public void rollback() throws SQLException { con.rollback(); } @Override public boolean isClosed() throws SQLException { return con.isClosed(); } @Override public DatabaseMetaData getMetaData() throws SQLException { return con.getMetaData(); } @Override public void setReadOnly(boolean readOnly) throws SQLException { con.setReadOnly(readOnly); } @Override public boolean isReadOnly() throws SQLException { return con.isReadOnly(); } @Override public void setCatalog(String catalog) throws SQLException { con.setCatalog(catalog); } @Override public String getCatalog() throws SQLException { return con.getCatalog(); } @Override public void setTransactionIsolation(int level) throws SQLException { con.setTransactionIsolation(level); } @Override public int getTransactionIsolation() throws SQLException { return con.getTransactionIsolation(); } @Override public SQLWarning getWarnings() throws SQLException { return con.getWarnings(); } @Override public void clearWarnings() throws SQLException { con.clearWarnings(); } @Override public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException { return con.createStatement(resultSetType,resultSetConcurrency); } @Override public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { return con.prepareStatement(sql,resultSetType,resultSetConcurrency); } @Override public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { return con.prepareCall(sql,resultSetType,resultSetConcurrency); } @Override public Map<String, Class<?>> getTypeMap() throws SQLException { return con.getTypeMap(); } @Override public void setTypeMap(Map<String, Class<?>> map) throws SQLException { con.setTypeMap(map); } @Override public void setHoldability(int holdability) throws SQLException { con.setHoldability(holdability); } @Override public int getHoldability() throws SQLException { return con.getHoldability(); } @Override public Savepoint setSavepoint() throws SQLException { return con.setSavepoint(); } @Override public Savepoint setSavepoint(String name) throws SQLException { return con.setSavepoint(name); } @Override public void rollback(Savepoint savepoint) throws SQLException { con.rollback(savepoint); } @Override public void releaseSavepoint(Savepoint savepoint) throws SQLException { con.releaseSavepoint(savepoint); } @Override public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { return con.createStatement(resultSetType,resultSetConcurrency,resultSetHoldability); } @Override public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { return con.prepareStatement(sql,resultSetType,resultSetConcurrency,resultSetHoldability); } @Override public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { return con.prepareCall(sql,resultSetType,resultSetConcurrency,resultSetHoldability); } @Override public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException { return con.prepareStatement(sql,autoGeneratedKeys); } @Override public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException { return con.prepareStatement(sql,columnIndexes); } @Override public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException { return con.prepareStatement(sql,columnNames); } @Override public Clob createClob() throws SQLException { return con.createClob(); } @Override public Blob createBlob() throws SQLException { return con.createBlob(); } @Override public NClob createNClob() throws SQLException { return con.createNClob(); } @Override public SQLXML createSQLXML() throws SQLException { return con.createSQLXML(); } @Override public boolean isValid(int timeout) throws SQLException { return con.isValid(timeout); } @Override public void setClientInfo(String name, String value) throws SQLClientInfoException { con.setClientInfo(name,value); } @Override public void setClientInfo(Properties properties) throws SQLClientInfoException { con.setClientInfo(properties); } @Override public String getClientInfo(String name) throws SQLException { return con.getClientInfo(name); } @Override public Properties getClientInfo() throws SQLException { return con.getClientInfo(); } @Override public Array createArrayOf(String typeName, Object[] elements) throws SQLException { return con.createArrayOf(typeName,elements); } @Override public Struct createStruct(String typeName, Object[] attributes) throws SQLException { return con.createStruct(typeName,attributes); } @Override public void setSchema(String schema) throws SQLException { con.setSchema(schema); } @Override public String getSchema() throws SQLException { return con.getSchema(); } @Override public void abort(Executor executor) throws SQLException { con.abort(executor); } @Override public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException { con.setNetworkTimeout(executor,milliseconds); } @Override public int getNetworkTimeout() throws SQLException { return con.getNetworkTimeout(); } @Override public <T> T unwrap(Class<T> iface) throws SQLException { return con.unwrap(iface); } @Override public boolean isWrapperFor(Class<?> iface) throws SQLException { return con.isWrapperFor(iface); } }
package demo02.myDataSourse; import java.sql.*; import java.util.List; //1.定义一个类,继承适配器类 public class demomyConnection extends myAdapter { //2.定义连接对象和连接池容器对象的成员变量 private Connection con; private List<Connection> pool; //3.通过有参构造方法为成员变量赋值 public demomyConnection(Connection con, List<Connection> pool) { super(con); this.con = con; this.pool = pool; } //4.重写close方法,完成归还连接 @Override public void close(){ pool.add(con); } }
package demo02.myDataSourse; import demo02.utils.JDBCUtils; import javax.sql.DataSource; import java.io.PrintWriter; import java.sql.Connection; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.logging.Logger; //自定义数据库连接池 public class demoDataSourse implements DataSource{ //1.准备容器,用于保存多个连接对象 private static List<Connection> pool = Collections.synchronizedList(new ArrayList<>()); //2.定义静态代码块,通过工具类获取10个连接对象 static{ for(int i=1;i<=10;i++){ Connection con = JDBCUtils.getConnection(); pool.add(con); } } //3.重写getConnection(),用于获取一个连接对象 @Override public Connection getConnection() throws SQLException { if(pool.size()>0){ Connection con = pool.remove(0); //通过自定义的连接对象,对原有的连接对象进行包装 demomyConnection mycon = new demomyConnection(con,pool); return mycon; }else{ throw new RuntimeException("连接数量已用尽"); } } //4.定义getSize方法,获取连接池容器的大小 public int getSize(){ return pool.size(); } @Override public Connection getConnection(String username, String password) throws SQLException { return null; } @Override public <T> T unwrap(Class<T> iface) throws SQLException { return null; } @Override public boolean isWrapperFor(Class<?> iface) throws SQLException { return false; } @Override public PrintWriter getLogWriter() throws SQLException { return null; } @Override public void setLogWriter(PrintWriter out) throws SQLException { } @Override public void setLoginTimeout(int seconds) throws SQLException { } @Override public int getLoginTimeout() throws SQLException { return 0; } @Override public Logger getParentLogger() throws SQLFeatureNotSupportedException { return null; } }
package demo02.myDataSourse; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; public class demoDataSourseTest { public static void main(String[] args) throws Exception { //1.创建连接池对象 demoDataSourse dataSourse = new demoDataSourse(); System.out.println("使用之前的数量" + dataSourse.getSize()); //2.通过连接池对象获取连接对象 Connection con = dataSourse.getConnection(); //3.查询学生表的全部信息 String sql = "SELECT * FROM student"; PreparedStatement pst = con.prepareStatement(sql); //4.执行sql语句,接收结果集 ResultSet rs = pst.executeQuery(); //5.处理结果集 while(rs.next()){ System.out.println(rs.getInt("sid")+"\t"+rs.getString("name")+"\t"+rs.getInt("age")+"\t"+rs.getDate("birthday")); } //6.释放资源 rs.close(); pst.close(); con.close();//用完以后,进行归还 System.out.println("使用之后的数量" + dataSourse.getSize()); } }
动态代理:
- 在不改变目标对象方法的情况下对方法进行增强
组成:
- 被代理对象:真实的对象
- 代理对象:内存中的一个对象
- 代理对象是被代理对象的增强,没有具体的Java文件进行表示,在内存中进行体现
要求:
- 代理对象和被代理对象实现相同的接口
实现:
- Proxy.newProxyInstance()
- 返回一个代理对象
- 参数:
- 1.类加载器
- 如stu.getClass().getClassLoader()
- 2.接口类型Class数组
- 如new Class[]{StudentInterface.class}
- 3.代理规则
- 通过匿名内部类的方式使用InvocationHandler接口
- 这个接口里有一个invoke方法
- 第一个参数不需要关心,一般用不到
- 第二个参数method:我们所要调用某个对象真实的方法的Method对象
- 第三个参数args:是传递给增强执行方法的具体的参数
动态代理实例演示
- 被代理对象
package demo02.laodemo; public class Student implements StudentInterface{ public void eat(String name){ System.out.println("学生吃"+name); } public void study(){ System.out.println("在家自学"); } }
- 接口
package demo02.laodemo; public interface StudentInterface { void eat(String name); void study(); }
- 代理对象
package demo02.laodemo; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class Test { public static void main(String[] args) { Student stu = new Student(); //要求:在不改动Student类中任何的代码的前提下,通过study方法输出一句话:我在刷codeforces StudentInterface proxystu = (StudentInterface) Proxy.newProxyInstance(stu.getClass().getClassLoader(), new Class[]{StudentInterface.class}, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //执行Student类中所有的方法都会经过invoke方法 //对method方法进行判断 //如果是study,则对其进行增强;如果不是,还调用学生对象原有的功能即可 if(method.getName().equals("study")){ System.out.println("我在刷codeforces"); return null; }else{ return method.invoke(stu,args); } } }); proxystu.eat("米饭"); proxystu.study(); } }
动态代理方式归还数据库连接的思想
- 我们可以通过Proxy来完成对Connection实现类对象的代理
- 代理过程中判断如果执行的是close方法,就将连接归还池中
- 如果是其它方法则调用连接对象原来的功能即可
动态代理方式归还数据库连接的实现步骤
- 1.定义一个类,实现DataSource接口
- 2.定义一个容器,用于保存多个Connection连接对象
- 3.定义静态代码块,通过JDBC工具类获取10个连接保存到容器中
- 4.重写getConnection方法,从容器中获取一个连接
- 5.通过Proxy代理,如果是close方法,就将连接归还池中,如果是其它方法则调用原有功能
- 6.定义getSize方法,用于获取容器的大小并返回
动态代理方式实例演示
package demo02.myDataSourse; import demo02.utils.JDBCUtils; import javax.sql.DataSource; import java.io.PrintWriter; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.sql.Connection; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.logging.Logger; //自定义数据库连接池 public class demoDataSourse implements DataSource{ //1.准备容器,用于保存多个连接对象 private static List<Connection> pool = Collections.synchronizedList(new ArrayList<>()); //2.定义静态代码块,通过工具类获取10个连接对象 static{ for(int i=1;i<=10;i++){ Connection con = JDBCUtils.getConnection(); pool.add(con); } } //3.重写getConnection(),用于获取一个连接对象 @Override public Connection getConnection() throws SQLException { if(pool.size()>0){ Connection con = pool.remove(0); //执行Connection实现类连接对象所有的方法都会经过invoke //如果是close方法,就将连接归还池中,如果是其它方法则调用原有功能 Connection proxycon = (Connection) Proxy.newProxyInstance(con.getClass().getClassLoader(), new Class[]{Connection.class}, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if(method.getName().equals("close")){ pool.add(con); return null; }else{ return method.invoke(con,args); } } }); return proxycon; }else{ throw new RuntimeException("连接数量已用尽"); } } //4.定义getSize方法,获取连接池容器的大小 public int getSize(){ return pool.size(); } @Override public Connection getConnection(String username, String password) throws SQLException { return null; } @Override public <T> T unwrap(Class<T> iface) throws SQLException { return null; } @Override public boolean isWrapperFor(Class<?> iface) throws SQLException { return false; } @Override public PrintWriter getLogWriter() throws SQLException { return null; } @Override public void setLogWriter(PrintWriter out) throws SQLException { } @Override public void setLoginTimeout(int seconds) throws SQLException { } @Override public int getLoginTimeout() throws SQLException { return 0; } @Override public Logger getParentLogger() throws SQLFeatureNotSupportedException { return null; } }
边栏推荐
- RHCE first day
- What is a driver signature and how does the driver get a digital signature?
- 经典的拓扑排序问题——LeetCode207 课程表+LeetCode210 课程表II
- The computer doesn't know what to uninstall, can't open the calculator, can't edit screenshots, can't open txt files, and so on
- What is utxo?
- Arduino uno driver universe 1.8 'TFT SPI screen example demonstration (including data package)
- 【自】-刷题-数组
- 2022年G2电站锅炉司炉考试题库模拟考试平台操作
- 深度剖析集成学习Xgboost
- 添加构建依赖项报错
猜你喜欢
SAP 临时表空间错误处理
零视科技 H5S视频平台 GetUserInfo 信息泄漏漏洞 CNVD-2020-67113
MySQL log management, backup and recovery
field injection is not recommended 的解决办法
2022年R2移动式压力容器充装考题模拟考试平台操作
什么是驱动程序签名,驱动程序如何获取数字签名?
Equipped with a new generation of ultra safe cellular batteries, Sihao aipao is available from 139900 yuan
2022 welder (Junior) work license questions and answers
宝塔 phpmyadmin未授权访问漏洞
MySQL introduction
随机推荐
零视科技 H5S视频平台 GetUserInfo 信息泄漏漏洞 CNVD-2020-67113
What is a driver signature and how does the driver get a digital signature?
新一代超安全蜂窝电池 思皓爱跑上市13.99万元起售
Pycharm new project
Best practices for migration of kingbasees v8.3 to v8.6 of Jincang database (2. Compatibility of kingbasees v8.3 and v8.6)
宝塔 phpmyadmin未授权访问漏洞
电商数据模型设计
Kingbasees client programming interface guide ODBC (4. Create data source)
PHP 海报二维码合成
Jincang database kingbasees client Programming Interface Guide - ODBC feature support constraints
使用Pytorch快速训练网络模型
经典双栈实现队列,注意遍历栈的判定条件修改。
Deep analysis of integrated learning AdaBoost
小程序editor富文本编辑使用及rich-text解析富文本
(22) two permutation (DP), package delivery (greedy)
2022年R2移动式压力容器充装考题模拟考试平台操作
EN 1935建筑五金.单轴铰链—CE认证
经典的拓扑排序问题——LeetCode207 课程表+LeetCode210 课程表II
多传感器融合定位(一)——3D激光里程计
Zero view h5s video platform getUserInfo information disclosure vulnerability cnvd-2020-67113