對於實體中包含有公共欄位,像create_at,create_time,update_at,update_time來說,我們沒有必要在每個實體的crud操作中複製同樣的程式碼,這樣程式碼的味道很壞,我們應該使用mybatis的攔截器機制,將公共欄位統一處理;當然mybatis-puls在實現上更加優雅,它幫我們封裝了MetaObjectHandler
介面,我們可以重寫insertFill
和updateFill
來完成公共欄位的統一填充,詳細可看我這篇文章《springboot~MyBatisPlus中使用@TableField完成欄位自動填充》。
mybatis中的實現
-
需要實現org.apache.ibatis.plugin.Interceptor介面
-
在intercept方法中實現業務核心邏輯
-
在SqlSessionFactory中註冊你的intercept類
-
攔截器程式碼
@Intercepts({ @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }) })
public class FillCreateAndUpdateFieldInterceptor implements Interceptor {
static final Logger logger = LoggerFactory.getLogger(FillCreateAndUpdateFieldInterceptor.class);
@Override
public Object intercept(Invocation invocation) throws Throwable {
Object[] args = invocation.getArgs();
MappedStatement ms = (MappedStatement) args[0];
Object parameter = args[1];
if (ms.getId().contains("insert") || ms.getId().contains("update")) {
if (SecurityUtils.getAuthentication() != null) {
if (parameter instanceof BaseEntity) {
BaseEntity entity = (BaseEntity) parameter;
if (ms.getId().contains("insert")) {
entity.setCreateBy(SecurityUtils.getAuthentication().getName());
entity.setCreateTime(new Date());
}
entity.setUpdateBy(SecurityUtils.getAuthentication().getName());
entity.setUpdateTime(new Date());
}
}
}
}
- 自定義SqlSessionFactory的bean
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
String typeAliasesPackage = env.getProperty("mybatis.typeAliasesPackage");
String mapperLocations = env.getProperty("mybatis.mapperLocations");
String configLocation = env.getProperty("mybatis.configLocation");
typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage);
VFS.addImplClass(SpringBootVFS.class);
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
sessionFactory.setMapperLocations(resolveMapperLocations(StringUtils.split(mapperLocations, ",")));
sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation));
SqlSessionFactory result = sessionFactory.getObject();
// 註冊自定義攔截器
result.getConfiguration().addInterceptor(new FillCreateAndUpdateFieldInterceptor());
return result;
}
透過上面的程式碼,我們就完成了公共欄位的統一處理。