goodluck 发表于 2010-2-20 14:57:05

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

<p >要实现对数据库的操作,离不开数据源(DataSource)或者连接(Connection),但是通常来说对数据库的操作都应该放在DAO中,而DAO又不应该与应用服务器相关联,所以一般都使用连接(Connection)。现在我们这里就有一个问题了,怎么在拦截器中获得连接。我想可以通过两种方式获得:<BR>在分别讨论这两种方法之前,我们需要先讨论一下在处理数据库的时候的异常的处理。我这里做了一个TransactionException继承至RuntimeException然后在拦截器里面抛出,再又应用框架处理这个异常。下面试这个类的代码:<BR>public class TransactionException extends RuntimeException {<BR>    private Throwable superException;<BR>    private String myMessage;<BR><BR>    public TransactionException(Throwable throwable){<BR>      super(throwable);<BR>      this.superException = throwable;<BR>    }<BR><BR>    public TransactionException(Throwable throwable,String message){<BR>      super(message,throwable);<BR>      this.superException = throwable;<BR>      this.myMessage = message;<BR>    }<BR><BR>    /**<BR>   * @return Returns the myMessage.<BR>   */<BR>    public String getMessage() {<BR>      return myMessage;<BR>    }<BR><BR>    /**<BR>   * @return Returns the superException.<BR>   */<BR>    public Throwable getSuperException() {<BR>      return superException;<BR>    }<BR><BR>    /**<BR>   * @param myMessage The myMessage to set.<BR>   */<BR>    public void setMyMessage(String message) {<BR>      this.myMessage = message;<BR>    }<BR><BR>    /**<BR>   * @param superException The superException to set.<BR>   */<BR>    public void setSuperException(Throwable superException) {<BR>      this.superException = superException;<BR>    }<BR><BR><BR>}<BR>1)    通过方法的第一个参数传进去<BR>l    DAO<BR>import java.sql.Connection;<BR><BR>public class TestDao {<BR>    public void insertA(Connection con,String a,String b,……){<BR>      …………………………………………<BR>一系列操作<BR>…………………………………………<BR>    }<BR><BR>    public String queryA(Connection con,…….){<BR>    …………………………………………<BR>一系列操作<BR>…………………………………………<BR>}<BR><BR>    public void updateA(Connection con,…….){<BR>      …………………………………………<BR>一系列操作<BR>…………………………………………<BR>}<BR>}<BR><BR>l    拦截器<BR>import java.sql.Connection;<BR>import java.sql.SQLException;<BR>import java.util.ArrayList;<BR>import java.util.List;<BR><BR>public class TransactionInterceptor implements Interceptor {<BR><BR>    public void before(InvokeJniInfo invInfo) {<BR>      if(isNeedTransactions(invInfo)){<BR>            Connection conn = (Connection) invInfo.getArgs();<BR>            try {<BR>                conn.setAutoCommit(false);<BR>            } catch (SQLException e) {<BR>                throw new TransactionException(e);<BR>            }<BR>      }<BR>    }<BR><BR>    public void after(InvokeJniInfo invInfo) {<BR>      if(isNeedTransactions(invInfo)){<BR>            Connection conn = (Connection) invInfo.getArgs();<BR>            try {<BR>                conn.commit();<BR>            } catch (SQLException e) {<BR>                throw new TransactionException(e);<BR>            }finally{<BR>                if(conn != null){<BR>                  try {<BR>                        conn.close();<BR>                  } catch (SQLException e) {<BR>                        throw new TransactionException(e,"Close Connection is failure!");<BR>                  }<BR>                }<BR>            }<BR>      }<BR>    }<BR><BR>    public void exceptionThrow(InvokeJniInfo invInfo) {<BR>      if(isNeedTransactions(invInfo)){<BR>            Connection conn = (Connection) invInfo.getArgs();<BR>            try {<BR>                conn.rollback();<BR>            } catch (SQLException e) {<BR>                throw new TransactionException(e);<BR>            }finally{<BR>                if(conn != null){<BR>                  try {<BR>                        conn.close();<BR>                  } catch (SQLException e) {<BR>                        throw new TransactionException(e,"Close Connection is failure!");<BR>                  }<BR>                }<BR>            }<BR>      }<BR>    }<BR><BR>    private List getNeedTransaction(){<BR>      List needTransactions = new ArrayList();<BR>      needTransactions.add("insert");<BR>      needTransactions.add("update");<BR>      return needTransactions;<BR>    }<BR><BR>    private boolean isNeedTransactions(InvokeJniInfo invInfo){<BR>      String needTransaction = "";<BR>      List needTransactions = getNeedTransaction();<BR>      for(int i = 0;i<needTransactions.size();i++){<BR>            needTransaction = (String)needTransactions.get(i);<BR>            if(invInfo.getMethod().getName().startsWith(needTransaction)){<BR>                return true;<BR>            }<BR>      }<BR>      return false;<BR>    }<BR>}<BR><BR>需要注意的是:getNeedTransaction就是需要进行事务处理的方法的开头,这个方法可以写成一个从配置文件里面去读,这里我就写死在里面了。只是对insert和update开头的方法进行事务控制。<BR>2)    将Connection对象放在ThreadLocal中<BR>l    ConnectionUtil类:<BR>import java.sql.Connection;<BR><BR>public final class ConnectionUtil {<BR>    private static ThreadLocal connections = new ThreadLocal();<BR>    public static Connection getConnection(){<BR>      Connection conn = null;<BR>      conn = (Connection) connections.get();<BR>      if(conn == null){<BR>            conn = getRealConnection();<BR>            connections.set(conn);<BR>      }<BR>      return conn;<BR>    }<BR>    public static void realseConnection(Connection conn){<BR>      connections.set(null);<BR>    }<BR>    private static Connection getRealConnection() {<BR>      实现自己获取连接的代码<BR>      return null;<BR>    }<BR>}<BR>l    DAO类<BR>public class TestDao {<BR>    public void insertA(String a,String b){<BR>      Connection conn = getConnection();<BR>      …………………………………………<BR>一系列操作<BR>…………………………………………<BR>    }<BR>      public String queryA(Connection con,…….){<BR>      Connection conn = getConnection();<BR>    …………………………………………<BR>一系列操作<BR>…………………………………………<BR>}<BR><BR>    public void updateA(Connection con,…….){<BR>Connection conn = getConnection();<BR>      …………………………………………<BR>一系列操作<BR>…………………………………………<BR>}<BR><BR>    private Connection getConnection(){<BR>      return ConnectionUtil.getConnection();<BR>    }<BR><BR>}<BR>l    拦截器<BR>import java.sql.Connection;<BR>import java.sql.SQLException;<BR>import java.util.ArrayList;<BR>import java.util.List;<BR><BR>public class TransactionInterceptor implements Interceptor {<BR><BR>    public void before(InvokeJniInfo invInfo) {<BR>      if(isNeedTransactions(invInfo)){<BR>            Connection conn = getConnection();<BR>            try {<BR>                conn.setAutoCommit(false);<BR>            } catch (SQLException e) {<BR>                throw new TransactionException(e);<BR>            }<BR>      }<BR>    }<BR><BR>    public void after(InvokeJniInfo invInfo) {<BR>      if(isNeedTransactions(invInfo)){<BR>            Connection conn = getConnection();<BR>            try {<BR>                conn.commit();<BR>            } catch (SQLException e) {<BR>                throw new TransactionException(e);<BR>            }finally{<BR>                if(conn != null){<BR>                  try {<BR>                        conn.close();<BR>                        releaseConnection(conn);<BR>                  } catch (SQLException e) {<BR>                        throw new TransactionException(e,"Close Connection is failure!");<BR>                  }<BR>                }<BR>            }<BR>      }<BR>    }<BR><BR>    public void exceptionThrow(InvokeJniInfo invInfo) {<BR>      if(isNeedTransactions(invInfo)){<BR>            Connection conn = getConnection();<BR>            try {<BR>                conn.rollback();<BR>            } catch (SQLException e) {<BR>                throw new TransactionException(e);<BR>            }finally{<BR>                if(conn != null){<BR>                  try {<BR>                        conn.close();<BR>                        releaseConnection(conn);<BR>                  } catch (SQLException e) {<BR>                        throw new TransactionException(e,"Close Connection is failure!");<BR>                  }<BR>                }<BR>            }<BR>      }<BR>    }<BR><BR>    private Connection getConnection(){<BR>      return ConnectionUtil.getConnection();<BR>    }<BR><BR>    private void releaseConnection(Connection conn){<BR>      ConnectionUtil.releaseConnection(conn);<BR>    }<BR>    private List getNeedTransaction(){<BR>      List needTransactions = new ArrayList();<BR>      needTransactions.add("insert");<BR>      needTransactions.add("update");<BR>      return needTransactions;<BR>    }<BR><BR>    private boolean isNeedTransactions(InvokeJniInfo invInfo){<BR>      String needTransaction = "";<BR>      List needTransactions = getNeedTransaction();<BR>      for(int i = 0;i<needTransactions.size();i++){<BR>            needTransaction = (String)needTransactions.get(i);<BR>            if(invInfo.getMethod().getName().startsWith(needTransaction)){<BR>                return true;<BR>            }<BR>      }<BR>      return false;<BR>    }<BR>}<BR>    最后将这个拦截器添加到AOP拦截框架中去,InterceptorHandler类中的getIntercetors方法中添加一个:<BR><BR>    private synchronized List getIntercetors(){<BR>      if(null == interceptors){<BR>            interceptors = new ArrayList();<BR>            ……………………………………<BR>interceptors.add(new TransactionInterceptor ());<BR>            ……………………………………<BR>      }<BR>      return interceptors;<BR>}<BR><BR>到此全部ok!<BR><FONT face="Times New Roman"> </FONT><p align="center"></p></p>
页: [1]
查看完整版本: 使用动态代理实现用AOP对数据库进行操作