写在前面的话
在博文《搭建拥有数据交互的 SpringBoot 》中,我们已经使用 SpringBoot3 整合了 MyBatis,在博文《企业实战分享 · MyBatis 使用合集》中,介绍了企业开发实战中,关于 MyBatis 的常见用法。
本系列博文以 MyBatis 插件的介绍和云应用开篇,围绕 MyBatis 进一步展开,让我们开始吧。
MyBatis 插件用法
技术简介
MyBatis 是一个流行的 Java 持久层框架,支持自定义插件以扩展其功能。MyBatis 插件可以用来拦截执行过程中的某些操作,比如查询、插入、更新和删除等。
MyBatis 插件允许你拦截 MyBatis 运行时的关键操作,例如:
- SQL 语句执行前后的拦截:可以修改 SQL 语句、添加日志、进行权限控制等。
- 结果集处理前后的拦截:可以对结果集行格式化、加密、脱敏等操作。
- 缓存操作的拦截:可以自定义缓存策略、添加缓存监控等。
基础入门
实现步骤:
定义插件接口:实现 Interceptor 接口,并重写 intercept() 方法。
实现插件逻辑: intercept() 方法中,根据拦截的目标对象类型和方法名,执行相应的逻辑。
注册插件:在 MyBatis 配置文件中,使用 标签注册插件。
Step1、创建插件类:
插件类需要实现 Interceptor 接口,并重写 intercept 方法。
@Intercepts({
@Signature(type = Executor.class, method = "update", args = {String.class, Object.class}),
@Signature(type = Executor.class, method = "query", args = {String.class, Object.class})
})
public class MyPlugin implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
// 在这里可以添加自定义逻辑
System.out.println("Before method: " + invocation.getMethod().getName());
Object result = invocation.proceed(); // 执行原方法
System.out.println("After method: " + invocation.getMethod().getName());
return result;
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
// 可以在这里设置插件的属性
}
}
Step2、在 MyBatis 配置文件中注册插件:
<plugins>
<plugin interceptor="com.lw.sbdemo2.MyPlugin">
<property name="propertyName" value="propertyValue"/>
</plugin>
</plugins>
注意事项
- 插件的实现需要谨慎,避免影响 MyBatis 的正常运行。
- 插件的性能需要考虑,避免引入额外的性能开销。
- 插件的代码需要进行充的测试,确保其稳定性和可靠性。
常用场景
耗时记录:
可以使用插件来记录 SQL 执行的时间,帮助开发者分析性能瓶颈。
SQL 日志记录:
可以记录所有执行的 SQL 语句,方便调试和审计。
数据加密/解密:
在插入或查询数据时,可以对敏感数据进行加密或解密。
分页插件:
可以实现自定义的分页逻辑,自动为查询添加分页参数。
权限控制:
在执行数据库操作之前,可以检查用户的权限。
其他场景:
SQL 语句拦截
日志记录:记录 SQL 语句、参数、执行时间等信息,方便调试和性能分析。
权限控:根据用户权限过滤 SQL 语句,防止非法操作。
SQL 审计:对 SQL 语句进行安全审计,防止 SQL 注入攻击。
结果集处理拦截
数据格式化:将数据库中的数据格式化为前端需要的格式。
数据脱敏:对敏感数据进行脱敏处理,保护用户隐私。
数据加密:敏感数据进行加密处理,提高数据安全性。
缓存操作拦截
自定义缓存策略:根据业需求,实现不同的缓存策略,例如二级缓存、分布式缓存等。
缓存监控:监控缓存命中、缓存大小等信息,优化缓存性能。
返回值与优先级
插件的返回值含义
MyBatis 插件的 intercept 方法的返回值是一个 Object,它的含义取决于被拦截的方法:
对于查询方法(如 query):
返回值通常是查询结果,比如一个对象或对象列表。
对于更新方法(如 update):
返回值通常是一个整数,表示受影响的行数。
对于其他方法(如 delete):
返回值也通常是一个整数,表示删除的行数。
如果在 intercept 方法中调用 invocation.proceed(),则会继续执行被拦截的方法,并返回其结果。如果在 intercept 方法中直接返回一个值,则会覆盖被拦截方法的返回值。
多个插件的优先级
当多个插件被注册时,它们的执行顺序是按照它们在 MyBatis 配置文件中出现的顺序来决定的。也就是说,先注册的插件会先执行,后注册的插件会后执行。
假设有两个插件 PluginA 和 PluginB,在 MyBatis 配置文件中如下注册:
<plugins>
<plugin interceptor="com.example.PluginA"/>
<plugin interceptor="com.example.PluginB"/>
</plugins>
在这种情况下,当执行某个 SQL 操作时,PluginA 的 intercept 方法会先被调用,然后是 PluginB 的 intercept 方法。
插件中断的情况
如果在某个插件的 intercept 方法中直接返回一个值(而不是调用 invocation.proceed()),那么后续的插件将不会被执行。这意味着该插件可以“中断”后续插件的执行。
总结陈词
此篇文章介绍了 MyBatis 的插件相关知识,只是入门案例,仅供学习参考,后续将展开介绍具体插件。
MyBatis 插件提供了一种灵活的方式来扩展框架的功能。通过实现 Interceptor 接口,开发者可以在执行 SQL 操作之前和之后插入自定义逻辑。常见的插件场景包括性能监控、SQL 日志记录、数据加密、分页和权限控制等。
💗 后续会逐步分享企业实际开发中的实战经验,有需要交流的可以联系博主。