MyBatis 拦截器在批量插入操作时失效通常是由于以下原因:
@Intercepts({
@Signature(type = Executor.class,
method = "update",
args = {MappedStatement.class, Object.class})
})
public class MyInterceptor implements Interceptor {
// 拦截器实现
}
确保你的拦截器签名包含所有可能的 Executor 类型。
批量操作通常使用 BatchExecutor
,确保你的拦截器能处理这种类型:
@Intercepts({
@Signature(type = Executor.class,
method = "update",
args = {MappedStatement.class, Object.class}),
@Signature(type = Executor.class,
method = "flushStatements",
args = {})
})
public class MyBatchInterceptor implements Interceptor {
// 拦截器实现
}
在拦截器中添加对批量操作的判断:
@Override
public Object intercept(Invocation invocation) throws Throwable {
Object[] args = invocation.getArgs();
MappedStatement ms = (MappedStatement) args[0];
Object parameter = args[1];
// 判断是否为批量操作
if (parameter instanceof Collection) {
// 处理批量逻辑
Collection<?> collection = (Collection<?>) parameter;
for (Object obj : collection) {
// 对每个对象进行处理
}
}
return invocation.proceed();
}
确保你的 SqlSessionFactory 配置了支持拦截器的 Executor:
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
// 设置Executor类型,如果需要支持批量操作
org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
configuration.setDefaultExecutorType(ExecutorType.BATCH);
sessionFactory.setConfiguration(configuration);
// 添加拦截器
sessionFactory.setPlugins(new Interceptor[]{new MyBatchInterceptor()});
return sessionFactory.getObject();
}
如果你使用的是 MyBatis 的 foreach
标签进行批量插入,确保拦截器能处理这种 SQL 构建方式:
<insert id="batchInsert" parameterType="java.util.List">
INSERT INTO table_name (column1, column2)
VALUES
<foreach collection="list" item="item" separator=",">
(#{item.field1}, #{item.field2})
</foreach>
</insert>
@Intercepts
注解覆盖了所有需要拦截的方法如果以上方法仍不能解决问题,可能需要检查 MyBatis 版本是否存在已知问题,或考虑使用其他方式实现批量操作时的逻辑处理。