Java动态代理连接数据库,模拟连接池
2010-12-02 14:53
501 查看
经常操作数据库的关闭,连接,很浪费系统资源,导致系统运行效率低,本人做了一个模拟连接池的程序,使用代理模式,代理数据库的关闭方法,当用户点击关闭连接时,数据库连接并没有关闭,而是被挂起,等待另一个用户来拿,这样,就减少了用户频繁的操作数据库的关闭,连接,下面是我自己写的代码。请各位看看有什么不好的地方,麻烦各位大虾指出
1. 代理模式
代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
代理模式一般涉及到的角色有:
抽象角色:声明真实对象和代理对象的共同接口; (在此我没有写抽象角色,直接代理真实对象)
代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。
真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。
数据库实体ConnBean.java
package com.sve.proxydb;
public class ConnBean {
/* private String url = null;
private String driver = null;
private String user = null;
private String password = null;
*/
public String getUrl() {
return "jdbc:oracle:thin:@192.168.1.24:1521:ora10g";
}
public String getDriver() {
return "oracle.jdbc.driver.OracleDriver";
}
public String getUser() {
return "scott";
}
public String getPassword() {
return "sa";
}
}
(这个可以使用xml记录这些值,本人认为使用xml会更好,可是我用了老是报错,所以我就没有用了)
真实角色Strategy.java
package com.sve.proxydb;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;
public class Strategy {
public static int maxConn = 0; //最大连接数
public static int minConn = 0; //最小连接数
public static int initConn = 0; //初始化连接
public static int freeConn = 0; //空闲连接
public static int currentConn = 0; //当前连接
public ConnBean connBean = new ConnBean();
ProxyDB proxyDB = new ProxyDB();
//定义list存放释放的数据库连接
public static LinkedList<Connection> connlist = new LinkedList<Connection>();
//构造方法,获得最大连接值,初始化多少连接数
public Strategy(int maxConn, int initConn){
this.maxConn = maxConn;
this.initConn = initConn;
//初始化连接
init();
}
public Strategy(){}
//初始化数据库连接
public void init(){
for(int i = 0; i < this.initConn; i++){
connlist.addLast(createConn());
//获得连接
this.freeConn++; //增加空闲连接数
}
for(int i = 0; i < this.initConn; i++){
System.out.println(connlist.get(i));
}
}
/**
* 创建连接
* @return 返回新创建的连接
* @throws ClassNotFoundException
* @throws SQLException
*/
public Connection createConn(){
proxyDB = new ProxyDB(new Strategy());
Connection conn = null;
try{
Class.forName(connBean.getDriver());
conn = DriverManager.getConnection(connBean.getUrl(),
connBean.getUser(), connBean.getPassword());
}catch(Exception e){
e.printStackTrace();
}
//判断当前连接是否小于最大连接
if(this.currentConn <= this.maxConn)
return proxyDB.getConnInstance(conn);
return null;
}
/**
* 获得连接
* @return 返回连接
*/
public Connection getConn(){
//判断空闲连接是否大于当前连接
//System.out.println(connlist.size() + " " + connBean.currentConn + " "+connBean.freeConn);
if(this.freeConn >= this.currentConn){
this.freeConn--;
this.currentConn++;
System.out.println(connlist.size() + " " + this.currentConn + " "+this.freeConn);
return connlist.removeFirst();
}
this.currentConn++;
System.out.println(connlist.size() + " " + this.currentConn + " "+this.freeConn);
return createConn();
}
}
代理角色ProxyDB.java
package com.sve.proxydb;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
public class ProxyDB implements InvocationHandler{
public Connection saveConn = null; //存入数组的空闲连接
public Connection conn = null; //用于获得对象的连接
public Strategy staStrategy;
//在构造方法里获得staStrategy对象
public ProxyDB(Strategy staStrategy){
this.staStrategy = staStrategy;
}
public ProxyDB(){}
//获得连接实例
public Connection getConnInstance(Connection conn){
this.conn = conn;
saveConn = (Connection) Proxy.newProxyInstance(this.getClass().getClassLoader()
, new Class[]{Connection.class }, this);
return saveConn;
}
//处理代理的方法
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
//判断是否是执行关闭命令
if("close".equals(method.getName())){
staStrategy.currentConn--;
staStrategy.freeConn++;
staStrategy.connlist.add(saveConn); //将释放的连接放入list
//System.out.println(staStrategy.connlist.size() + " " + staStrategy.currentConn + " "+staStrategy.freeConn);
return null;
}
return method.invoke(conn, args);
}
}
好了,可以测试了,(*^__^*) 嘻嘻……
1. 代理模式
代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
代理模式一般涉及到的角色有:
抽象角色:声明真实对象和代理对象的共同接口; (在此我没有写抽象角色,直接代理真实对象)
代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。
真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。
数据库实体ConnBean.java
package com.sve.proxydb;
public class ConnBean {
/* private String url = null;
private String driver = null;
private String user = null;
private String password = null;
*/
public String getUrl() {
return "jdbc:oracle:thin:@192.168.1.24:1521:ora10g";
}
public String getDriver() {
return "oracle.jdbc.driver.OracleDriver";
}
public String getUser() {
return "scott";
}
public String getPassword() {
return "sa";
}
}
(这个可以使用xml记录这些值,本人认为使用xml会更好,可是我用了老是报错,所以我就没有用了)
真实角色Strategy.java
package com.sve.proxydb;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;
public class Strategy {
public static int maxConn = 0; //最大连接数
public static int minConn = 0; //最小连接数
public static int initConn = 0; //初始化连接
public static int freeConn = 0; //空闲连接
public static int currentConn = 0; //当前连接
public ConnBean connBean = new ConnBean();
ProxyDB proxyDB = new ProxyDB();
//定义list存放释放的数据库连接
public static LinkedList<Connection> connlist = new LinkedList<Connection>();
//构造方法,获得最大连接值,初始化多少连接数
public Strategy(int maxConn, int initConn){
this.maxConn = maxConn;
this.initConn = initConn;
//初始化连接
init();
}
public Strategy(){}
//初始化数据库连接
public void init(){
for(int i = 0; i < this.initConn; i++){
connlist.addLast(createConn());
//获得连接
this.freeConn++; //增加空闲连接数
}
for(int i = 0; i < this.initConn; i++){
System.out.println(connlist.get(i));
}
}
/**
* 创建连接
* @return 返回新创建的连接
* @throws ClassNotFoundException
* @throws SQLException
*/
public Connection createConn(){
proxyDB = new ProxyDB(new Strategy());
Connection conn = null;
try{
Class.forName(connBean.getDriver());
conn = DriverManager.getConnection(connBean.getUrl(),
connBean.getUser(), connBean.getPassword());
}catch(Exception e){
e.printStackTrace();
}
//判断当前连接是否小于最大连接
if(this.currentConn <= this.maxConn)
return proxyDB.getConnInstance(conn);
return null;
}
/**
* 获得连接
* @return 返回连接
*/
public Connection getConn(){
//判断空闲连接是否大于当前连接
//System.out.println(connlist.size() + " " + connBean.currentConn + " "+connBean.freeConn);
if(this.freeConn >= this.currentConn){
this.freeConn--;
this.currentConn++;
System.out.println(connlist.size() + " " + this.currentConn + " "+this.freeConn);
return connlist.removeFirst();
}
this.currentConn++;
System.out.println(connlist.size() + " " + this.currentConn + " "+this.freeConn);
return createConn();
}
}
代理角色ProxyDB.java
package com.sve.proxydb;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
public class ProxyDB implements InvocationHandler{
public Connection saveConn = null; //存入数组的空闲连接
public Connection conn = null; //用于获得对象的连接
public Strategy staStrategy;
//在构造方法里获得staStrategy对象
public ProxyDB(Strategy staStrategy){
this.staStrategy = staStrategy;
}
public ProxyDB(){}
//获得连接实例
public Connection getConnInstance(Connection conn){
this.conn = conn;
saveConn = (Connection) Proxy.newProxyInstance(this.getClass().getClassLoader()
, new Class[]{Connection.class }, this);
return saveConn;
}
//处理代理的方法
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
//判断是否是执行关闭命令
if("close".equals(method.getName())){
staStrategy.currentConn--;
staStrategy.freeConn++;
staStrategy.connlist.add(saveConn); //将释放的连接放入list
//System.out.println(staStrategy.connlist.size() + " " + staStrategy.currentConn + " "+staStrategy.freeConn);
return null;
}
return method.invoke(conn, args);
}
}
好了,可以测试了,(*^__^*) 嘻嘻……
相关文章推荐
- 在Java中利用动态代理实现数据库连接与事务的自动管理
- 通过动态代理(Proxy)实现的数据库连接池的创建连接与归还链接的操作的简单的实现流程
- 通过动态代理(Proxy)实现的数据库连接池的创建连接与归还链接的操作的简单的实现流程
- Java 的动态代理实例(JDBC的数据库的连接池(DataSource))
- 在Java中利用动态代理实现数据库连接与事务的自动管理
- 动态代理模拟连接池
- java动态代理原理及简单模拟
- Java工程中动态改变Hibernate的数据库连接信息总结
- 通过代理类实现java连接数据库(使用dao层操作数据)实例分享
- 又一次闲来无聊,使用Java的动态代理机制来模拟AOP
- Java动态代理实现模拟RMI远程方法调用
- Java 数据库系列教程--DBCP连接池连接数据库
- java 通过连接池来创建连接数据库
- java 数据库连接池 涂鸦模拟
- Java动态代理模拟spring的AOP
- Java中用动态代理实现标准的DataSource数据源连接池
- java连接数据库方式(一):传统JDBC + 连接池
- 利用php中的eval来模拟java中的动态代理
- JAVA 动态替换代理IP并模拟POST请求
- java 代理连接数据库