# 使用Mybatis自定义插件实现不侵入业务的公共参数自动追加
## 引言:公共参数处理的重要性
在实际的后端开发中,我们经常遇到需要向每个SQL语句中自动添加公共参数的情况,如用户ID、操作时间、租户ID等。手动为每一个Mapper接口方法添加这些参数不仅繁琐,而且易出错,不符合DRY(Don't Repeat Yourself)原则。Mybatis作为一款优秀的持久层框架,提供了强大的插件机制,让我们可以通过自定义插件来实现公共参数的自动追加,从而达到解耦业务逻辑,提高开发效率的目的。
## 一、Mybatis插件机制简介
**1.1 Mybatis插件原理**
Mybatis的插件机制基于Java的动态代理,通过对SqlSession和Executor等核心接口进行拦截,可以在执行SQL之前或之后插入自定义逻辑。通过`Interceptor`接口,我们可以定制自己的拦截器,对SQL执行过程进行增强。
**1.2 插件注册与顺序**
在Mybatis配置文件(mybatis-config.xml)中,通过`<plugins>`标签可以注册插件,并通过`<plugin>`子标签指定插件类。插件的执行顺序非常重要,根据`@Intercepts`注解声明的拦截方法优先级决定。
```xml
<plugins>
<plugin interceptor="com.example.MyCustomPlugin">
<!-- 可选属性,用于调整插件执行顺序 -->
<property name="order" value="1"/>
</plugin>
</plugins>
```
## 二、自定义插件实现公共参数追加
**2.1 创建自定义插件类**
首先,创建一个实现`Interceptor`接口的类,例如`CommonParamAutoAppendPlugin`,并在其中定义拦截方法。
```java
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import java.util.Properties;
@Intercepts({
@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}),
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})
})
public class CommonParamAutoAppendPlugin implements Interceptor {
// ... 其他代码
}
```
**2.2 拦截方法实现**
在拦截方法中,我们需要获取到即将执行的`MappedStatement`对象以及参数对象,然后追加公共参数,最后调用目标方法执行原生的SQL操作。
```java
@Override
public Object intercept(Invocation invocation) throws Throwable {
MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
Object parameterObject = invocation.getArgs()[1];
// 这里仅作示例,实际项目中应从上下文中获取公共参数
String commonParam = "your_common_param";
// 将公共参数添加至参数对象
if (parameterObject instanceof Map) {
((Map) parameterObject).put("common_param", commonParam);
} else if (parameterObject != null && !mappedStatement.getBoundSql(parameterObject).hasAdditionalParameter("common_param")) {
// 若参数对象非Map类型且未包含公共参数,则利用反射为其添加
Field field = parameterObject.getClass().getDeclaredField("common_param");
field.setAccessible(true);
field.set(parameterObject, common_param);
}
return invocation.proceed();
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
// 可以在此处初始化插件所需的属性
}
```
## 三、应用与测试
**3.1 配置插件**
在Mybatis的全局配置文件中,将自定义插件进行注册:
```xml
<!-- 配置自定义插件 -->
<plugins>
<plugin interceptor="com.example.CommonParamAutoAppendPlugin" />
</plugins>
```
**3.2 测试验证**
编写单元测试或者在实际业务中验证,无论何时执行更新或查询操作,SQL参数中都会自动包含预先设定的公共参数。
## 结语:提升开发效率与维护性
通过本文,我们了解了如何在Mybatis中使用自定义插件实现公共参数的自动追加,这样不仅能减少重复工作,降低出错概率,同时也有助于提升代码的可读性和维护性。当然,在实际开发过程中,还需要根据具体业务场景进行相应的优化和完善,如公共参数的获取方式、兼容多种类型的参数对象等。
以上只是一个基础示例,真正的实践可能涉及到更复杂的场景和处理逻辑,但只要掌握Mybatis插件的核心原理,就能灵活应对各种需求,让我们的后端开发更加高效、规范。