📄 connectionhome.java
字号:
/**
* @author 肖建军
* 定义数据库连接的代理类
*/
package com.sunrise.chnl.sql;
import java.lang.reflect.*;
import java.sql.*;
import com.sunrise.chnl.obj.PublicBean;
public class ConnectionHome implements InvocationHandler {
//定义连接
private Connection conn = null;
//定义监控连接创建的语句
private Statement statRef = null;
private PreparedStatement prestatRef = null;
private CallableStatement cstRef = null;
//是否支持事务标志
private boolean supportTransaction = false;
//数据库的忙状态
private boolean isOnline = false;
//最后一次访问时间
long lastAccessTime = 0;
//定义要接管的函数的名字
String CREATESTATE = "createStatement";
String CLOSE = "close";
String PREPARESTATEMENT = "prepareStatement";
String PREPARECALL = "prepareCall";
String COMMIT = "commit";
String ROLLBACK = "rollback";
/**
* 构造函数,采用私有,防止被直接创建
* @param param 连接参数
*/
private ConnectionHome(ConnectionParam param) {
//记录日至
try{
//创建连接
Class.forName(param.getDriver()).newInstance();
conn = DriverManager.getConnection(param.getUrl(),param.getUser(), param.getPassword());
DatabaseMetaData dm = null;
dm = conn.getMetaData();
//判断是否支持事务
supportTransaction = dm.supportsTransactions();
}catch(Exception e){
PublicBean.writelog("ERR-CH0001:失败原因:" + e.toString(),0);
}
}
/**
* 检查连接是否被使用
* @param proxy
* @param method
* @param args
* @return
* @throws java.lang.Throwable
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object obj = null;
//设置最后一次使用时间,以便及时清除超时的连接
lastAccessTime = System.currentTimeMillis();
System.out.println(method.getName());
//判断是否调用了close的方法,如果调用close方法则把连接置为无用状态
if(CLOSE.equals(method.getName())){
//设置不使用标志
setOnline(false);
//检查是否有后续工作,清除该连接无用资源
if (statRef != null) statRef.close();
if (prestatRef != null) prestatRef.close();
return null;
}
//判断是使用了createStatement语句
if (CREATESTATE.equals(method.getName())){
obj = method.invoke(conn, args);
statRef = (Statement)obj;
//记录语句
return obj;
}
//判断是使用了prepareStatement语句
if (PREPARESTATEMENT.equals(method.getName())){
obj = method.invoke(conn, args);
prestatRef = (PreparedStatement)obj;
return obj;
}
//判断是否使用了prepareCall语句
if(PREPARECALL.equals(method.getName())){
obj = method.invoke(conn, args);
cstRef = (CallableStatement)obj;
return obj;
}
//如果不支持事务,就不执行该事物的代码
if ((COMMIT.equals(method.getName())||ROLLBACK.equals(method.getName())) && (!isSupportTransaction())) return null;
obj = method.invoke(conn, args);
return obj;
}
/**
* 创建连接的工厂,只能让工厂调用
* @param factory 要调用工厂,并且一定被正确初始化
* @param param 连接参数
* @return 连接
*/
public static ConnectionHome getConnection(ConnectionFactory factory, ConnectionParam param) {
if (factory.isCreate()){
//判断是否正确初始化的工厂 _
ConnectionHome _conn = new ConnectionHome(param);
return _conn;
}
else return null;
}
/**
* @return
*/
public Connection getFreeConnection() {
//返回数据库连接conn的接管类,以便截住close方法
Class[] interfaces = conn.getClass().getInterfaces();
if(interfaces==null||interfaces.length==0){
interfaces = new Class[1];
interfaces[0] = Connection.class;
}
Connection conn_tmp = (Connection)Proxy.newProxyInstance(conn.getClass().getClassLoader(),interfaces,this);
return conn_tmp;
}
/**
* 该方法真正的关闭了数据库的连接
* @throws SQLException
*/
void close() throws SQLException{
//由于类属性conn是没有被接管的连接,因此一旦调用close方法后就直接关闭连接
conn.close();
}
/**
* @param value
*/
public void setOnline(boolean value) {
isOnline = value;
}
/**
* @return
*/
public boolean getOnline() {
return isOnline;
}
/**
* @return
*/
public long getLastAccessTime(){
return lastAccessTime;
}
/**
* 判断是否支持事务
* @return boolean
*/
public boolean isSupportTransaction() {
return supportTransaction;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -