首页 | 互联网 | IT动态 | IT培训 | Cisco | Windows | Linux | Java | .Net | Oracle | 软件测试 | C/C++ | 嵌入式开发 | 存储世界 | 服务器
网络设备 | IDC | 安全 | 求职招聘 | 数字网校 | 网页设计 | 平面设计 | 技术专题 | 电子书下载 | 教学视频 | 源码下载 | 搜索 | 博客 | 论坛
中国IT实验室Linux频道
中国IT教育
Google
首页 资讯动态 认证考试 新手入门 核心技术 高级技术 J2EE J2ME Java&XML 开源技术 其他技术 RSS订阅 论坛 专题
您现在的位置: 中国IT实验室 >> Java >> 新手入门 >> 基础入门 >> 正文

用动态代理实现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            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!


 

【责编:Ken】

中国IT教育

相关产品和培训
文章评论
 友情推荐链接
 认证培训
 专题推荐

 ·关于Java框架技术专题
 ·XML全攻略技术专题
 ·JAVA开源技术介绍专题
 ·Java嵌入式开发之J2ME技术专题
 ·超前体验 Oracle 11g的5个新特性…
 ·揭密使用VB.NET的五个实用技巧
 ·Oracle和SQL Server常用函数对比专题…
 ·展现C#世界 C#程序设计专题…
 ·Java入门 Tomcat的配置技巧精华专题…
 ·Oracle RMAN物理备份技术详解…
 今日更新
 社区讨论
 博客论点
 频道精选
 Java 频道导航