问题描述
在配置多数据源的环境中,会为每个数据源创建一个独立的SqlSessionFactory
和SqlSessionTemplate
。使用MyBatisPlus的自动填充功能时失效,通常是因为没有正确配置每个数据源的自动填充处理器。
解决方案
1. 自定义自动填充处理器
首先需要实现一个自定义的自动填充处理器。这个处理器需要继承MetaObjectHandler
接口,并实现insertFill
和updateFill
方法。在这些方法中,可以定义自动填充的逻辑
@Component
@Primary
@Slf4j
public class DataSource2MetaObjectHandler implements MetaObjectHandler {
// 插入时执行
@Override
public void insertFill(MetaObject metaObject) {
this.setFieldValByName("createTime",LocalDateTime.now(),metaObject);
this.setFieldValByName("updateTime",LocalDateTime.now(),metaObject);
}
// 更新时执行
@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("updateTime", LocalDateTime.now(),metaObject);
}
}
2. 定义数据源配置类
首先,我们需要为每个数据源定义一个配置类。在这个类中,我们会配置数据源、SqlSessionFactory
和SqlSessionTemplate
。以下是一个示例配置类,用于配置名为db02
的数据源:
@Configuration
public class DataSourceConfigDB02 {
@Primary
@Bean("db02DataSource")
@ConfigurationProperties(prefix = "spring.datasource.db2")
public DataSource getDB02DataSource() {
return DruidDataSourceBuilder.create().build();
}
@Primary
@Bean("db02SqlSessionFactory")
public SqlSessionFactory db02SqlSessionFactory(@Qualifier("db02DataSource") DataSource dataSource) throws Exception {
MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
bean.setDataSource(dataSource);
// 设置mapper映射文件位置(如果有的话)
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/flowable/*.xml"));
// 全局配置
GlobalConfig globalConfig = new GlobalConfig();
globalConfig.setMetaObjectHandler(new DataSource2MetaObjectHandler()); // 使用自定义的自动填充处理器
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 配置拦截器
interceptor.addInnerInterceptor(new AutoFillInterceptor(globalConfig));
bean.setPlugins(interceptor);
return bean.getObject();
}
@Primary
@Bean("db02SqlSessionTemplate")
public SqlSessionTemplate db02SqlSessionTemplate(@Qualifier("db02SqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
注意,在上面的代码中,我们创建了一个GlobalConfig
对象,并设置了自定义的自动填充处理器DataSource2MetaObjectHandler
。然后,我们创建了一个MybatisPlusInterceptor
对象,并将自动填充拦截器AutoFillInterceptor
添加到其中。最后,我们将这个拦截器添加到SqlSessionFactory
中。
3. 在实体类中使用注解
最后,我们需要在实体类中使用MyBatisPlus提供的注解来指定哪些字段需要自动填充。例如:
@Data
public class SomeEntity {
private Long id;
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
}
在这个示例中,使用了@TableField
注解来指定createTime
字段在插入时自动填充,而updateTime
字段在插入和更新时都自动填充。
总结
单数据源只需要步骤1,3即可实现自动填充
多数据源多了步骤2,需要将自定义的自动填充处理器配置在 globalConfig
,并将这个 globalConfig
实例设置到需要使用的 SqlSessionFactory