使用动态代理实现用AOP对数据库进行操作

前几天写了“使用动态代理实现AOP功能”的文章,里面具的两个例子一个是记录日志,另一个是初始化一下参数,对实际应用不大,今天写一下在实际应用中比较常用的用AOP对数据库进行操作。
在前一篇文章中已经将整个框架打好,现在只需要实现一个完成数据库操做的拦截器就可以了,下面我们就来实现这个拦截器。
要实现对数据库的操作,离不开数据源(DataSource)或者连接(Connection),但是通常来说对数据库的操作都应该放在DAO中,而DAO又不应该与应用服务器相关联,所以一般都使用连接(Connection)。现在我们这里就有一个问题了,怎么在拦截器中获得连接。我想可以通过两种方式获得:
在分别讨论这两种方法之前,我们需要先讨论一下在处理数据库的时候的异常的处理。我这里做了一个TransactionException继承至RuntimeException然后在拦截器里面抛出,再又应用框架处理这个异常。下面试这个类的代码:


public class TransactionException extends RuntimeException {
private Throwable superException;
private String myMessage;

public TransactionException(Throwable throwable){
super(throwable);
this.superException = throwable;
}

public TransactionException(Throwable throwable,String message){
super(message,throwable);
this.superException = throwable;
this.myMessage = message;
}

/**
* @return Returns the myMessage.
*/
public String getMessage() {
return myMessage;
}

/**
* @return Returns the superException.
*/
public Throwable getSuperException() {
return superException;
}

/**
* @param myMessage The myMessage to set.
*/
public void setMyMessage(String message) {
this.myMessage = message;
}

/**
* @param superException The superException to set.
*/
public void setSuperException(Throwable superException) {
this.superException = superException;
}


}
1) 通过方法的第一个参数传进去
l DAO
import java.sql.Connection;

public class TestDao {
public void insertA(Connection con,String a,String b,……){
…………………………………………
一系列操作
…………………………………………
}

public String queryA(Connection con,…….){
…………………………………………
一系列操作
…………………………………………
}

public void updateA(Connection con,…….){
…………………………………………
一系列操作
…………………………………………
}
}

l 拦截器
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class TransactionInterceptor implements Interceptor {

public void before(InvokeJniInfo invInfo) {
if(isNeedTransactions(invInfo)){
Connection conn = (Connection) invInfo.getArgs()[0];
try {
conn.setAutoCommit(false);
} catch (SQLException e) {
throw new TransactionException(e);
}
}
}

public void after(InvokeJniInfo invInfo) {
if(isNeedTransactions(invInfo)){
Connection conn = (Connection) invInfo.getArgs()[0];
try {
conn.commit();
} catch (SQLException e) {
throw new TransactionException(e);
}finally{
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
throw new TransactionException(e,"Close Connection is failure!");
}
}
}
}
}

public void exceptionThrow(InvokeJniInfo invInfo) {
if(isNeedTransactions(invInfo)){
Connection conn = (Connection) invInfo.getArgs()[0];
try {
conn.rollback();
} catch (SQLException e) {
throw new TransactionException(e);
}finally{
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
throw new TransactionException(e,"Close Connection is failure!");
}
}
}
}
}

private List getNeedTransaction(){
List needTransactions = new ArrayList();
needTransactions.add("insert");
needTransactions.add("update");
return needTransactions;
}

private boolean isNeedTransactions(InvokeJniInfo invInfo){
String needTransaction = "";
List needTransactions = getNeedTransaction();
for(int i = 0;i<needTransactions.size();i++){
needTransaction = (String)needTransactions.get(i);
if(invInfo.getMethod().getName().startsWith(needTransaction)){
return true;
}
}
return false;
}
}

需要注意的是:getNeedTransaction就是需要进行事务处理的方法的开头,这个方法可以写成一个从配置文件里面去读,这里我就写死在里面了。只是对insert和update开头的方法进行事务控制。
2) 将Connection对象放在ThreadLocal中
l ConnectionUtil类:
import java.sql.Connection;

public final class ConnectionUtil {
private static ThreadLocal connections = new ThreadLocal();
public static Connection getConnection(){
Connection conn = null;
conn = (Connection) connections.get();
if(conn == null){
conn = getRealConnection();
connections.set(conn);
}
return conn;
}
public static void realseConnection(Connection conn){
connections.set(null);
}
private static Connection getRealConnection() {
实现自己获取连接的代码
return null;
}
}
l DAO类
public class TestDao {
public void insertA(String a,String b){
Connection conn = getConnection();
…………………………………………
一系列操作
…………………………………………
}
public String queryA(Connection con,…….){
Connection conn = getConnection();
…………………………………………
一系列操作
…………………………………………
}

public void updateA(Connection con,…….){
Connection conn = getConnection();
…………………………………………
一系列操作
…………………………………………
}

private Connection getConnection(){
return ConnectionUtil.getConnection();
}

}
l 拦截器
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class TransactionInterceptor implements Interceptor {

public void before(InvokeJniInfo invInfo) {
if(isNeedTransactions(invInfo)){
Connection conn = getConnection();
try {
conn.setAutoCommit(false);
} catch (SQLException e) {
throw new TransactionException(e);
}
}
}

public void after(InvokeJniInfo invInfo) {
if(isNeedTransactions(invInfo)){
Connection conn = getConnection();
try {
conn.commit();
} catch (SQLException e) {
throw new TransactionException(e);
}finally{
if(conn != null){
try {
conn.close();
releaseConnection(conn);
} catch (SQLException e) {
throw new TransactionException(e,"Close Connection is failure!");
}
}
}
}
}

public void exceptionThrow(InvokeJniInfo invInfo) {
if(isNeedTransactions(invInfo)){
Connection conn = getConnection();
try {
conn.rollback();
} catch (SQLException e) {
throw new TransactionException(e);
}finally{
if(conn != null){
try {
conn.close();
releaseConnection(conn);
} catch (SQLException e) {
throw new TransactionException(e,"Close Connection is failure!");
}
}
}
}
}

private Connection getConnection(){
return ConnectionUtil.getConnection();
}

private void releaseConnection(Connection conn){
ConnectionUtil.releaseConnection(conn);
}
private List getNeedTransaction(){
List needTransactions = new ArrayList();
needTransactions.add("insert");
needTransactions.add("update");
return needTransactions;
}

private boolean isNeedTransactions(InvokeJniInfo invInfo){
String needTransaction = "";
List needTransactions = getNeedTransaction();
for(int i = 0;i<needTransactions.size();i++){
needTransaction = (String)needTransactions.get(i);
if(invInfo.getMethod().getName().startsWith(needTransaction)){
return true;
}
}
return false;
}
}
最后将这个拦截器添加到AOP拦截框架中去,InterceptorHandler类中的getIntercetors方法中添加一个:

private synchronized List getIntercetors(){
if(null == interceptors){
interceptors = new ArrayList();
……………………………………
interceptors.add(new TransactionInterceptor ());
……………………………………
}
return interceptors;
}

到此全部ok!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值