MyBatis 四种类型拦截器

介绍

在 MyBatis 中,拦截器(Interceptor)是一种强大的机制,用于拦截 SQL 语句的执行过程,可以在执行 SQL 前后进行一些自定义的操作,比如日志记录、权限验证、性能监控等。在 MyBatis 中,拦截器主要通过实现 org.apache.ibatis.plugin.Interceptor 接口来实现。

MyBatis 四种类型拦截器

  1. ParameterHandler 拦截器

    • 在设置 SQL 语句的参数时触发,可以在参数设置前后进行自定义的处理。
  2. ResultSetHandler 拦截器

    • 在结果集(ResultSet)处理时触发,可以在结果集处理前后进行自定义的处理,比如将结果集映射到对象前进行一些额外的操作。
  3. StatementHandler 拦截器

    • 在 SQL 语句的执行过程中触发,可以在 SQL 语句执行前后进行自定义的处理,比如动态修改 SQL、增加额外的逻辑等。
  4. Executor 拦截器

    • 在执行器(Executor)执行增删改查操作时触发,可以在操作执行前后进行自定义的处理,比如监控执行时间、权限验证等。

MyBatis 拦截器执行流程

  1. 创建拦截器链

    • 当 MyBatis 创建 Configuration 配置对象时,会根据配置文件中的 <plugins> 标签配置,依次创建拦截器链。每个拦截器可以拦截 MyBatis 中的特定接口,比如 Executor、StatementHandler 等。
  2. 包装目标对象

    • 拦截器会包装目标对象(比如 Executor、StatementHandler 等),生成一个代理对象。这个代理对象实现了目标对象的接口,并且在方法调用时会触发拦截器的逻辑。
  3. 方法拦截逻辑

    • 当调用目标对象的方法时,代理对象会先执行拦截器的 intercept 方法。在这个方法中,可以对方法进行拦截并执行自定义的逻辑。通常,拦截器的 intercept 方法中会调用 Invocation.proceed() 方法来继续执行链中的下一个拦截器或者最终执行目标方法。
  4. 执行目标方法

    • Invocation.proceed() 方法执行完毕后,会继续执行目标对象的原始方法。如果拦截器链中还有其他拦截器,则会继续执行下一个拦截器的 intercept 方法,直到所有拦截器都执行完毕。
  5. 返回结果处理

    • 当所有拦截器的 intercept 方法执行完毕后,会返回最终的执行结果给调用方。

通过这种拦截器机制,MyBatis 提供了一种非常灵活的扩展方式,可以方便地在 SQL 执行过程中添加额外的功能,而不需要修改已有的业务代码。

### MyBatis 类型拦截器的使用与功能详解 MyBatis 提供了强大的拦截器机制,允许开发者在不修改框架核心逻辑的情况下扩展其行为。以下是 MyBatis四种主要类型拦截器的功能及使用方法: #### 1. **ParameterHandler 拦截器** `ParameterHandler` 是 MyBatis 中负责处理 SQL 参数的核心对象。通过拦截 `ParameterHandler`,可以实现对 SQL 参数的动态修改或增强功能。 - **功能**: 在 SQL 执行之前,拦截并修改传递给 JDBC 的参数值。例如,可以添加加密、格式化或其他预处理逻辑[^4]。 - **使用示例**: ```java @Intercepts({ @Signature(type = ParameterHandler.class, method = "setParameters", args = {PreparedStatement.class}) }) public class CustomParameterInterceptor implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { PreparedStatement statement = (PreparedStatement) invocation.getArgs()[0]; // 自定义逻辑,如修改参数值 statement.setString(1, "Customized Value"); return invocation.proceed(); } } ``` #### 2. **ResultSetHandler 拢截器** `ResultSetHandler` 负责将 JDBC 的 `ResultSet` 转换为 Java 对象列表。通过拦截此对象,可以自定义结果集的转换逻辑。 - **功能**: 修改或增强查询结果的映射过程。例如,可以在结果集中添加额外字段或进行数据脱敏处理[^5]。 - **使用示例**: ```java @Intercepts({ @Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class}) }) public class CustomResultSetInterceptor implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { Object result = invocation.proceed(); // 自定义逻辑,如对结果集进行后处理 return result; } } ``` #### 3. **StatementHandler 拦截器** `StatementHandler` 封装了 JDBC 的 `Statement` 操作,是 MyBatis 执行 SQL 的核心组件之一。通过拦截此对象,可以动态修改 SQL 或绑定参数。 - **功能**: 动态修改 SQL 语句或参数绑定逻辑。例如,可以根据业务需求动态生成分页 SQL 或添加条件。 - **使用示例**: ```java @Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class}) }) public class CustomStatementInterceptor implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { StatementHandler handler = (StatementHandler) invocation.getTarget(); BoundSql boundSql = handler.getBoundSql(); String sql = boundSql.getSql(); // 自定义逻辑,如修改 SQL String newSql = sql.replaceAll("SELECT", "SELECT TOP 10"); Field field = ReflectionUtils.findField(handler.getClass(), "delegate"); field.setAccessible(true); ReflectiveStatementHandler reflectiveHandler = (ReflectiveStatementHandler) field.get(handler); ReflectiveBoundSql reflectiveBoundSql = (ReflectiveBoundSql) reflectiveHandler.getBoundSql(); reflectiveBoundSql.sql = newSql; return invocation.proceed(); } } ``` #### 4. **Executor 拦截器** `Executor` 是 MyBatis 的执行器,负责 SQL 的调度和缓存管理。通过拦截 `Executor`,可以实现复杂的业务逻辑或性能优化。 - **功能**: 拦截增删改查操作,实现日志记录、缓存管理或事务控制等功能[^5]。 - **使用示例**: ```java @Intercepts({ @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}) }) public class CustomExecutorInterceptor implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { // 自定义逻辑,如记录日志或缓存结果 System.out.println("Executing query..."); return invocation.proceed(); } } ``` ### 配置拦截器 为了使拦截器生效,需要将其注册到 MyBatis 的配置文件中或通过代码方式加载: - **XML 配置**: ```xml <plugins> <plugin interceptor="com.example.CustomParameterInterceptor"/> <plugin interceptor="com.example.CustomResultSetInterceptor"/> <plugin interceptor="com.example.CustomStatementInterceptor"/> <plugin interceptor="com.example.CustomExecutorInterceptor"/> </plugins> ``` - **代码配置**: ```java SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); sessionFactory.setPlugins(new Interceptor[]{new CustomParameterInterceptor(), new CustomResultSetInterceptor()}); ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值