微站是什么,大连建站程序,找人做网站如何担保,教学参考网站建设在 Spring Boot 项目中使用 MyBatis Plus 时#xff0c;你可能会遇到 InnerInterceptor 这个概念。 InnerInterceptor 是 MyBatis Plus 提供的一种轻量级 SQL 拦截器#xff0c;它与传统的 MyBatis 拦截器#xff08;Interceptor#xff09;有所不同#xff0c;具有更简单… 在 Spring Boot 项目中使用 MyBatis Plus 时你可能会遇到 InnerInterceptor 这个概念。 InnerInterceptor 是 MyBatis Plus 提供的一种轻量级 SQL 拦截器它与传统的 MyBatis 拦截器Interceptor有所不同具有更简单、更高效的特点并且更专注于 SQL 执行层面的拦截。本文将详细介绍 InnerInterceptor 的原理、用法和最佳实践并提供代码示例。
一、为什么需要 InnerInterceptor
更轻量级 相比于传统的 InterceptorInnerInterceptor 更加轻量级减少了不必要的拦截开销提高了性能。更专注于 SQL 执行 InnerInterceptor 专注于 SQL 执行层面可以让你更方便地修改 SQL 语句、参数或结果。简化配置 InnerInterceptor 的配置更加简单无需手动注册MyBatis Plus 会自动识别并注册。易于扩展你可以通过实现 InnerInterceptor 接口自定义 SQL 拦截逻辑。与 MyBatis Plus 无缝集成InnerInterceptor 与 MyBatis Plus 的其他功能无缝集成可以更好地发挥 MyBatis Plus 的优势。内置丰富功能 MyBatis Plus 提供了许多内置的 InnerInterceptor 实现如分页插件、乐观锁插件、SQL性能分析插件等可以直接使用。
二、InnerInterceptor 与 Interceptor 的区别
拦截范围 Interceptor 可以拦截 MyBatis 的 Executor、ParameterHandler、ResultSetHandler 和 StatementHandler 等组件拦截范围更广。 InnerInterceptor 主要拦截 SQL 执行过程中的 StatementHandler拦截范围更窄但更专注于 SQL 执行。执行时机 Interceptor 可以拦截 SQL 执行过程中的多个阶段例如参数处理、SQL 预编译、结果处理等。 InnerInterceptor 主要拦截 StatementHandler 的 prepare 和 query 方法更专注于 SQL 语句的准备和执行阶段。配置方式 Interceptor 需要在 MyBatis 配置文件或 Spring Bean 中手动注册。 InnerInterceptor 通过 MyBatis Plus 提供的 MybatisPlusInterceptor 统一注册管理无需手动注册。代码复杂度 Interceptor 的代码相对复杂需要处理 Invocation 对象并手动调用 proceed 方法。 InnerInterceptor 的代码更加简洁只需要重写对应的方法。性能 Interceptor 由于拦截范围更广可能会带来一定的性能开销。 InnerInterceptor 由于拦截范围更窄性能更高。
三、InnerInterceptor 的核心方法
void beforePrepare(StatementHandler sh, Connection connection,Integer transactionTimeout): 在 SQL 语句预编译之前调用。void beforeQuery(StatementHandler sh, Connection connection, Integer transactionTimeout): 在 SQL 语句执行之前调用。void afterQuery(StatementHandler sh, Connection connection, Integer transactionTimeout, Object result) 在 SQL 查询执行后调用。void beforeUpdate(StatementHandler sh, Connection connection, Integer transactionTimeout): 在执行 INSERT 或 UPDATE 语句之前调用。void afterUpdate(StatementHandler sh, Connection connection, Integer transactionTimeout,Object result): 在执行 INSERT 或 UPDATE 语句之后调用。
四、实践使用 InnerInterceptor 修改 SQL 语句
4.1 创建 InnerInterceptor 实现类
import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.parser.CCJSqlParserManager;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.Select;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.springframework.stereotype.Component;import java.io.StringReader;
import java.sql.SQLException;Component
Slf4j
public class MyInnerInterceptor implements InnerInterceptor {Overridepublic void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {String sql boundSql.getSql();try {PluginUtils.MPBoundSql mpBs PluginUtils.mpBoundSql(boundSql);//sql处理String filterSql addFilterCondition(sql);log.info(修改过后的sql:{}, filterSql);//修改sqlmpBs.sql(filterSql);} catch (Exception e) {log.warn(动态修改sql:{}异常, sql, e);throw new SQLException(添加数据权限异常);}}public String addFilterCondition(String originalSql) throws JSQLParserException {CCJSqlParserManager parserManager new CCJSqlParserManager();Select select (Select) parserManager.parse(new StringReader(originalSql));PlainSelect plain (PlainSelect) select.getSelectBody();Expression where_expression plain.getWhere();// 这里可以根据需要增加过滤条件if (where_expression null) {plain.setWhere(CCJSqlParserUtil.parseCondExpression(age 35));}return plain.toString();}
}4.2 配置 MybatisPlusInterceptor
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.extend.chk.interceptor.MyInnerInterceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;import javax.annotation.PostConstruct;
import java.util.List;Configuration
public class MyBatisPlusConfig {Autowiredprivate ListSqlSessionFactory sqlSessionFactoryList;Autowiredprivate MyInnerInterceptor myInnerInterceptor;/*** 添加Mybatis拦截器* 主要是为了保证数据权限拦截器在分页插件拦截器之前执行sql的修改如果不在这里手动添加的话PageInterceptor会先执行* 先添加的拦截器后执行*/PostConstructpublic void addMybatisInterceptor() {for (SqlSessionFactory sqlSessionFactory : sqlSessionFactoryList) {org.apache.ibatis.session.Configuration configuration sqlSessionFactory.getConfiguration();//将数据权限拦截器添加到MybatisPlusInterceptor拦截器链MybatisPlusInterceptor mybatisPlusInterceptor new MybatisPlusInterceptor();mybatisPlusInterceptor.addInnerInterceptor(myInnerInterceptor);//先添加PageHelper分页插件拦截器再添加MybatisPlusInterceptor拦截器//configuration.addInterceptor(new PageInterceptor());configuration.addInterceptor(mybatisPlusInterceptor);}}
}4.3 使用 InnerInterceptor 现在你执行任何 SQL 语句都会被 InnerInterceptor 拦截你可以看到 SQL 语句已经被修改。
修改过后的sql:SELECT count(0) FROM t_user_info WHERE age 35
修改过后的sql:SELECT id, name, password, age, status, last_login_time, token, create_by, create_time, update_by, update_time, remark FROM t_user_info WHERE age 35 LIMIT ?五、内置拦截器 除了自定义拦截器外MyBatis-Plus 还提供了多个内置拦截器可以直接使用或作为参考来创建自己的拦截器。以下是几个常用的内置拦截器
PaginationInterceptor分页插件支持多种数据库的分页查询。PerformanceAnalyzerInterceptor性能分析插件记录每条 SQL 的执行时间和影响行数。OptimisticLockerInterceptor乐观锁插件用于防止并发更新时的数据覆盖问题。BlockAttackInterceptor阻止恶意攻击插件防止批量删除或更新操作导致数据丢失。
六、常见应用场景
SQL 日志记录如上文所示记录每次 SQL 执行的时间、参数及结果便于调试和性能分析。分页插件动态地为查询语句添加分页条件而无需修改原有的 Mapper 文件。SQL 性能监控统计每条 SQL 的执行次数、平均耗时等指标帮助识别潜在的性能瓶颈。缓存实现基于拦截器实现简单的查询结果缓存减少不必要的数据库访问。数据脱敏在查询结果返回之前对敏感字段进行加密或替换确保数据安全。权限控制在 SQL 执行前检查用户权限防止未经授权的操作。
七、最佳实践
按需选择拦截器 根据实际需求选择合适的拦截器如果需要修改 SQL 语句、参数或结果可以使用 InnerInterceptor如果需要拦截 MyBatis 的其他组件可以使用 Interceptor。细粒度控制 可以根据 MappedStatement 的 ID 或 SQL 语句内容细粒度控制 InnerInterceptor 的执行范围。使用内置的 InnerInterceptor MyBatis Plus 提供了许多内置的 InnerInterceptor 实现如分页插件、乐观锁插件、SQL 性能分析插件等可以直接使用无需重复开发。避免耗时操作 InnerInterceptor 会在 SQL 执行的关键节点执行避免在其中执行耗时的操作以免影响性能。异常处理: 在 InnerInterceptor 方法中使用 try-catch 代码块处理可能抛出的异常避免影响正常业务逻辑。配置顺序: 如果存在多个 InnerInterceptorMybatis Plus 会根据 addInnerInterceptor 方法的调用顺序进行执行。使用 MyBatis Plus 工具类 MyBatis Plus 提供了一些工具类例如 PluginUtils可以方便地访问和修改 SQL 语句、参数等信息。