`
dyllove98
  • 浏览: 1409718 次
  • 性别: Icon_minigender_1
  • 来自: 济南
博客专栏
73a48ce3-d397-3b94-9f5d-49eb2ab017ab
Eclipse Rcp/R...
浏览量:39191
4322ac12-0ba9-3ac3-a3cf-b2f587fdfd3f
项目管理checkList...
浏览量:80274
4fb6ad91-52a6-307a-9e4f-816b4a7ce416
哲理故事与管理之道
浏览量:133401
社区版块
存档分类
最新评论

使用动态代理实现用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!
分享到:
评论

相关推荐

    java分页 动态代理 aop实现

    这些代码可能涉及到如何创建分页对象,如何与数据库交互获取分页数据,以及如何在AOP中使用动态代理进行拦截和处理。 总的来说,Java分页、动态代理和AOP是Java开发中的关键技术,它们能帮助我们构建出更加高效、可...

    WCF路由、免代理、实现AOP拦截源码附数据库

    在WCF中,实现AOP拦截器可以让我们在服务调用前后执行特定的逻辑,比如添加日志、验证权限或处理异常。 在本DEMO中,AOP拦截器被用来在消息传递过程中捕获和处理消息。这可能包括验证请求的合法性、添加操作日志、...

    使用JAVA中的动态代理实现数据库连接池.rar_数据库连接池_连接池

    在Java编程中,数据库连接池是一种管理数据库连接的机制,它允许程序在多个请求之间...这个压缩包中的"使用JAVA中的动态代理实现数据库连接池"文档可能包含了更详细的实现细节和技术说明,可以进一步阅读以深入了解。

    Spring 动态代理和aop切面编程例子

    在Java中,有两种主要的动态代理实现方式:JDK动态代理和CGLIB动态代理。JDK动态代理基于接口实现,它要求被代理的对象必须实现至少一个接口;而CGLIB则是通过字节码技术生成一个类的子类来实现代理,因此即使目标类...

    Spring mvc mybatis plus 实现AOP 切面日志系统

    本项目“Spring MVC Mybatis Plus 实现AOP 切面日志系统”旨在提供一个基础的日志记录框架,能够自动追踪和记录应用程序的关键操作,同时支持数据持久化到数据库中,方便后期分析和问题排查。下面将详细介绍这些技术...

    Java的动态代理、反射机制和数据库连接池技术

    这种技术常用于实现AOP(面向切面编程),如日志记录、性能监控、事务管理等。Java的动态代理主要依赖于`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口。Proxy类用于创建代理对象,而...

    SpringAop学习笔记以及实现Demo

    4. **事务管理Demo**:结合Spring的事务管理特性,展示了如何使用AOP实现数据库操作的事务控制。 通过这些示例,你可以深入理解Spring AOP的工作原理,掌握其配置和使用方式,从而在实际项目中灵活地应用切面编程,...

    初探spring aop内部实现 java

    Spring AOP(面向切面编程)是Spring框架中的一个重要组件,它允许我们在不修改源代码的情况下,对程序的行为进行统一的管理和控制。本篇文章将深入探讨Spring AOP的内部实现,以及如何通过源代码理解其DataSource...

    基于Spring框架的AOP与MyBatis集成项目.zip

    本项目是一个基于Spring框架的应用程序,专注于使用Spring AOP(面向切面编程)和MyBatis进行数据库操作的集成。项目涵盖了从基本的Git操作到复杂的动态代理、事务管理以及数据库操作的实现。通过本项目,开发者可以...

    Java实现动态代理

    - 类似地,连接池工具包(如`connect类工具包`)可能也会使用动态代理来封装数据库连接的获取与释放,以实现更高效的资源管理。 4. **性能考虑**: - 虽然动态代理提供了强大的功能,但它的性能相对较低,因为...

    源码主要用于学习通过SpringBoot结合AOP简单实现数据库读写分离,数据源使用Alibaba Druid,数据.zip

    在本项目中,我们主要探讨如何使用SpringBoot与AOP(面向切面编程)来实现一个简单的数据库读写分离方案,同时利用阿里巴巴的Druid数据源。数据库读写分离是提高系统性能和可扩展性的重要手段,它将读操作和写操作...

    spring切面AOP所使用的jar包

    当一个业务操作涉及多个数据库操作时,可以使用AOP在开始和结束时自动进行事务的开启和提交,如果出现异常则回滚事务,保证数据的一致性。 总之,Spring AOP通过aspectjweaver.jar和aspectjrt.jar这两个关键库,...

    代理模式、AOP编程、jdbc支持

    代理模式分为静态代理和动态代理,静态代理是通过编写代理类来实现,而动态代理则可以在运行时动态创建代理对象。 在Java中,动态代理主要通过java.lang.reflect包中的Proxy和InvocationHandler接口实现。Proxy类...

    aop例子aop例子

    本例子是一个关于如何在Spring框架中实现AOP的应用实例。 标题中的"aop例子aop例子"表明我们将探讨Spring AOP的实践应用。Spring是Java领域中最流行的框架之一,它提供了对AOP的强大支持,使得我们可以方便地创建和...

    java动态代理实现自定义连接池

    动态代理通常用于实现AOP(面向切面编程)和拦截器模式,使得我们可以在不修改源代码的情况下增强或扩展已有对象的功能。在这个场景中,我们将动态代理应用于自定义连接池的实现,来提高数据库访问的效率和资源管理...

    使用SpringAop使用Oracle数据权限控制

    系统权限允许用户执行特定的数据库操作,如INSERT、UPDATE或DELETE,而对象权限则限制用户对特定表或视图的访问。我们可以创建自定义的角色,并分配适当的权限,以满足不同用户组的需求。 接下来,我们使用Spring ...

    spring aop jar 包

    Spring默认使用运行时织入,通过动态代理实现。 6. **代理(Proxy)**:代理是AOP的核心,它是目标对象的增强版本,负责在调用目标方法前后执行通知。 在使用Spring AOP时,我们可以通过XML配置或注解的方式来定义...

    Spring基础:Spring AOP简单使用

    在Spring中,AOP通过代理模式实现,可以分为JDK动态代理和CGLIB代理两种方式。 1. **AOP概念** - **切面(Aspect)**:切面是关注点的模块化,比如日志、安全检查等,它将分散在代码各处的相同关注点集中在一起。 ...

    java事务 - 使用动态代理

    在事务管理中,动态代理通常用于实现AOP(面向切面编程),将事务逻辑与业务逻辑分离。 1. **Java动态代理基础**: - Java动态代理基于Java反射API实现,主要涉及到`java.lang.reflect.Proxy`和`java.lang.reflect...

    spring动态代理

    连接池是数据库操作中常见的优化手段,动态代理可以用于监控连接的获取与释放,或者在每次连接使用前后执行特定的逻辑,如记录日志、检查连接状态等。 7. **应用场景**: Spring 动态代理常用于以下场景: - **...

Global site tag (gtag.js) - Google Analytics