技术开发 频道

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

  【IT168技术文档】

  要实现对数据库的操作,离不开数据源(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!

0
相关文章