mybatis 自定义实现拦截器插件Interceptor示例

下面是详细讲解“mybatis 自定义实现拦截器插件Interceptor示例”的完整攻略:

什么是MyBatis拦截器?

MyBatis 拦截器是一种插件技术,可自定义MyBatis框架自身的行为,是MyBatis框架中的重要组成部分。MyBatis 内置提供了多种拦截器,例如 ExecutorStatementHandler 等,每种拦截器都实现了不同的拦截点,拦截器具体实现方法是使用JDK 代理或者CGLIB 代理实现,通过对目标对象进行代理,可以拦截目标对象的方法调用,从而达到修改目标对象行为、增强功能等目的。

自定义拦截器示例1

在MyBatis总拦截器链执行前统计出SQL执行的时间。

// 定义拦截器类 
public class SqlCostInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // 获取StatementHandler
        StatementHandler stmtHandler = (StatementHandler) invocation.getTarget();
        // 获取被代理方法名称
        String methodId = invocation.getMethod().getName();
        MappedStatement mappedStatement = null;
        if (invocation.getTarget() instanceof RoutingStatementHandler) {
            // 分离代理对象链,即获取代理对象的真正对象
            RoutingStatementHandler statementHandler = (RoutingStatementHandler) invocation.getTarget();
            // 使用反射获取mappedStatement属性值
            mappedStatement = (MappedStatement) ReflectUtil.getFieldValue(statementHandler, "delegate.mappedStatement");
        } else if (invocation.getTarget() instanceof PreparedStatementHandler) {
            // 分离代理对象链,即获取代理对象的真正对象
            PreparedStatementHandler statementHandler = (PreparedStatementHandler) invocation.getTarget();
            // 使用反射获取mappedStatement属性值
            mappedStatement = (MappedStatement) ReflectUtil.getFieldValue(statementHandler, "delegate.mappedStatement");
        }
        // 获取sql语句
        BoundSql boundSql = stmtHandler.getBoundSql();
        String sql = boundSql.getSql();
        Object[] args = invocation.getArgs();
        // 获取SQL执行时间
        long start = System.currentTimeMillis();
        // 打印sql语句
        System.out.println(">>>>>>>>>>> 执行的sql语句为: " + sql);
        Object result = invocation.proceed();
        if (null != mappedStatement) {
            // 获取操作类型
            SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
            System.out.println(">>>>>>>>>>> 操作类型为: " + sqlCommandType);
        }
        // 输出SQL执行时间
        System.out.println(">>>>>>>>>>> SQL执行时间为:" + (System.currentTimeMillis() - start) + "ms");
        return result;
    }

    @Override
    public Object plugin(Object target) {
        // 使用默认的Plugin.wrap方法生成代理对象
        return Plugin.wrap(target, this);
    }
}

在示例中,我们通过自定义实现 Interceptor 接口,完成了对SQL语句执行前的统计SQL执行时间的功能。首先我们通过 invocation.getTarget() 获取到具体的执行方法对象,通过获取到的对象获取被代理方法名称、mappedStatement和BoundSql等信息,最后通过invocation.proceed() 实现对方法的调用,记录SQL语句执行的时间。

<!-- 将自定义拦截器注册到配置文件 -->
<plugins>
   <plugin interceptor="com.example.plugin.SqlCostInterceptor"></plugin>
</plugins>

将自定义的 SqlCostInterceptor 拦截器注册到 Ibatis 的核心配置文件中,如上所示。

自定义拦截器示例2

在MyBatis执行增删改操作时自动填充 createTime 和 updateTime 字段。

// 定义自定义插件类
@Intercepts({ @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }) })
public class CreateAndUpdateTimePlugin implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object target = invocation.getTarget();
        if (target instanceof Executor) {
            MappedStatement stmt = (MappedStatement) invocation.getArgs()[0];
            SqlCommandType sqlCommandType = stmt.getSqlCommandType();
            if (SqlCommandType.INSERT.equals(sqlCommandType) || SqlCommandType.UPDATE.equals(sqlCommandType)) {
                Object parameterObject = invocation.getArgs()[1];
                if (parameterObject instanceof BaseEntity) {
                    BaseEntity entity = (BaseEntity) parameterObject;
                    Date date = new Date();
                    if (SqlCommandType.INSERT.equals(sqlCommandType)) {
                        entity.setCreateTime(date);
                        entity.setUpdateTime(date);
                    } else if (SqlCommandType.UPDATE.equals(sqlCommandType)) {
                        entity.setUpdateTime(date);
                    }
                }
            }
        }
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }
}
<!-- 在mybatis中注册该自定义插件 -->
<plugins>
    <plugin interceptor="com.example.plugin.CreateAndUpdateTimePlugin"></plugin>
</plugins>

在示例2中,我们针对MyBatis新增、更新等操作,自定义实现插件类 CreateAndUpdateTimePlugin,对实体类中的createTime和updateTime进行自动填充。当增删改操作被执行时,判断是否需要对createTime和updateTime进行赋值,并执行插入或更新操作。最后将自定义的 CreateAndUpdateTimePlugin 插件注册到 Ibatis 的核心配置文件中。

以上就是MyBatis自定义实现拦截器插件Interceptor的两个示例。通过示例的讲解,希望能够帮助读者更好的了解MyBatis拦截器的原理和使用。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:mybatis 自定义实现拦截器插件Interceptor示例 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • 最新springboot中必须要了解的自动装配原理

    Spring Boot是一个基于Spring框架的快速开发框架,它通过自动装配来简化了Spring应用程序的配置。在最新的Spring Boot中,自动装配原理是必须要了解的。以下是最新Spring Boot中必须要了解的自动装配原理的完整攻略: 自动装配原理概述 自动装配是Spring Boot的核心特性之一,它通过自动扫描和自动配置来简化Spring应用…

    Java 2023年5月15日
    00
  • JAVA中的Configuration类详解

    下面是JAVA中的Configuration类详解的完整攻略。 什么是Configuration类 Configuration类是Java中的一个类,它主要用于读取、解析和处理配置文件。在Java中,通常会使用Properties类来读取和处理配置文件,但是Properties类仅支持读取key-value格式的配置文件,并且对于复杂的配置文件,它的处理能力…

    Java 2023年5月19日
    00
  • 详谈hibernate,jpa与spring data jpa三者之间的关系

    “Hibernate”是一个流行的ORM框架,它可以方便地将Java应用程序的对象模型映射到关系型数据库上。 “JPA”是Java持久化API的缩写,是Java EE规范的一部分。JPA是一个ORM规范,它定义了一些标准接口和类,供Java应用程序访问数据库。Hibernate是JPA的一个实现库,因此它可以用作JPA的实现。 “Spring Data JP…

    Java 2023年5月19日
    00
  • 值得收藏的9个提高代码运行效率的小技巧(推荐)

    值得收藏的9个提高代码运行效率的小技巧(推荐) 在代码编写时,优化程序的效率是非常重要的。本文提供了9个小技巧,可以帮助你提高代码的运行效率。 1. 使用map而不是for循环 使用 map() 命令可以在 Python 中更快地编写相同的代码。 它对列表中的每个元素执行相同的操作,并返回结果的列表。下面是一个示例: # 使用 for 循环 data = […

    Java 2023年5月23日
    00
  • struts2.2.3+spring3.1.0+mybatis3.1.0框架整合集成简单demo

    下面详细讲解“struts2.2.3+spring3.1.0+mybatis3.1.0框架整合集成简单demo”的完整攻略。 一、环境配置 下载并安装Java、Tomcat和MySQL; 搭建好Java和Tomcat的环境,配置好MySQL数据库。 二、搭建Struts2框架 创建Maven项目,引入Struts2的依赖,具体如下: <dependen…

    Java 2023年5月20日
    00
  • Java实现获得MySQL数据库中所有表的记录总数可行方法

    下面就来详细讲解“Java实现获得MySQL数据库中所有表的记录总数可行方法”的完整攻略。 1. 方案介绍 在 Java 中,我们可以使用 JDBC(Java Database Connectivity)API 来访问关系型数据库,其中包括 MySQL 数据库。我们可以通过执行 SQL 语句获取 MySQL 数据库中所有表的记录总数,主要有以下两种方法: 1…

    Java 2023年5月20日
    00
  • JAVA多种方法实现字符串反转

    下面是一份针对“JAVA多种方法实现字符串反转”的完整攻略: 前置知识 在学习Java字符串反转之前,需要了解字符串和字符数组的基本概念以及Java中常用的字符串处理方法,例如String的构造方法、length()、charAt()、substring()等。 方法一:使用StringBuilder或StringBuffer的reverse()方法 Str…

    Java 2023年5月26日
    00
  • java OpenTelemetry日志体系及缺陷解决方案

    Java OpenTelemetry日志体系及缺陷解决方案 什么是OpenTelemetry OpenTelemetry(简称OTel)是一个开放的,可观测性的框架,用于生成、收集,处理和打包跨系统的有关分布式实例的数据。可以帮助开发人员解决微服务监测以及调试等问题。 OpenTelemetry日志体系 OpenTelemetry通过日志(Log)的方式,允…

    Java 2023年5月25日
    00
合作推广
合作推广
分享本页
返回顶部