WEB开发网
开发学院WEB开发Jsp 使用动态代理实现用AOP对数据库进行操作 阅读

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

 2008-03-14 20:40:01 来源:WEB开发网   
核心提示:要实现对数据库的操作,离不开数据源(DataSource)或者连接(Connection),但是通常来说对数据库的操作都应该放在DAO中,使用动态代理实现用AOP对数据库进行操作,而DAO又不应该与应用服务器相关联,所以一般都使用连接(Connection),这里我就写死在里面了,只是对insert和update开头的
要实现对数据库的操作,离不开数据源(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      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      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!

Tags:使用 动态 代理

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接