最近在学习动态代理,总结之余写了个用AOP实现数据库日志打印的方法,有些地方还不完善,思路仅供参考
定义接口:
package Test_Proxy;
import java.sql.Connection;
import java.sql.Statement;
public interface ExcuteSQL {
public void executeInsert(String sql);
public void executeUpdate(String sql);
public void executeDelete(String sql);
public void executeQuery(String sql);
public void executeClose(Connection conn,Statement state);
//public void getConnect(String url, String username,String password);
}
实现接口类:
package Test_Proxy;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
public class ExecuteSqlImpl implements ExcuteSQL {
private Connection conn;
private Statement state;
public ExecuteSqlImpl(Connection conn, Statement state) {
super();
this.conn = conn;
this.state = state;
}
public Connection getConn() {
return conn;
}
public void setConn(Connection conn) {
this.conn = conn;
}
public Statement getState() {
return state;
}
public void setState(Statement state) {
this.state = state;
}
public void closeDB(Connection conn, Statement state) {
try {
if (!state.isClosed()&&state!=null) {
state.close();
}
if (!conn.isClosed()&&conn!=null) {
conn.close();
}
System.out.println("成功关闭数据库连接");
} catch (SQLException e) {
// TODO Auto-generated catch block
System.out.println("关闭数据库有异常");
e.printStackTrace();
}
}
@Override
public void executeInsert(String sql) {
// TODO Auto-generated method stub
try {
state.executeUpdate(sql);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
this.closeDB(conn, state);
}
}
@Override
public void executeUpdate(String sql) {
// TODO Auto-generated method stub
}
@Override
public void executeDelete(String sql) {
// TODO Auto-generated method stub
}
@Override
public void executeQuery(String sql) {
// TODO Auto-generated method stub
}
@Override
public void executeClose(Connection conn, Statement state) {
// TODO Auto-generated method stub
}
}
编写代理类
package Test_Proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ExecuteInvocation implements InvocationHandler {
private Object impl;
public ExecuteInvocation(Object impl) {
super();
this.impl = impl;
}
public Object getImpl() {
return impl;
}
public void setImpl(Object impl) {
this.impl = impl;
}
public static Object getInstance(Object obj){
Class cl=obj.getClass();
return Proxy.newProxyInstance(cl.getClassLoader(), cl.getInterfaces(), new ExecuteInvocation(obj));
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
System.out.println("执行sql开始!");
System.out.println("执行语句:"+args[0]);
method.invoke(impl, args[0]);
System.out.println("执行sql结束!");
return null;
}
}
测试代码:
package Test_Proxy;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class TestProxyMain {
public static void main(String[] args) {
String url = "jdbc:oracle:thin:@127.0.0.1:1521:orcl";
String username = "scott";
String password = "system";
Connection conn=null;
Statement state=null;
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
conn = DriverManager.getConnection(url, username, password);
state = conn.createStatement();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String sql = "insert into table_a(name,home) values('zhaowei','tongzhou')";
ExecuteSqlImpl executeImpl=new ExecuteSqlImpl(conn, state);
ExcuteSQL execute= (ExcuteSQL) ExecuteInvocation.getInstance(executeImpl);
execute.executeInsert(sql);
}
}
数据库连接需要优化和关闭还需要优化。
有问题和建议跪求指点!