我们在使用mybatis-plus
时,一般设备逻辑删除是非常简单的,基本上在yaml
等配置文件中做一下配置。然后在字段上注解@TableLogic
就可以了。有不清楚的,可以参考https://www.xiangcaowuyu.net/java/mybatis-plus-logical-deletion.html
但是今天在项目中,发现一个问题,就是明明也正确的进行了配置,但是在进行数据库操作时,发现逻辑删除并没有生效。
问题描述
先说一下问题先想,数据库指定的字段可以使用,但是指定是否逻辑删除的值时还是mybatis-plus
默认的0
和1
,并不是我指定的N
和Y
。
配置文件
先来看下我的配置文件。
mybatisPlus:
# 搜索指定包别名
typeAliasesPackage: net.xiangcaowuyu.**.domain
# 加载全局的配置文件
configLocation: classpath:mybatis/mybatis-config.xml
global-config:
db-config:
# 配置逻辑删除
logic-delete-field: del_flag
logic-not-delete-value: N
logic-delete-value: Y
通过配置文件,我指定数据库标记逻辑删除的字段为del_flag
,如果已经删除,标记为Y
,如果没有删除(默认值)就是N
。
实体
通过提取的公共实体,标记逻辑删除字段,如下
@Data
public class BaseEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 搜索值
*/
private String searchValue;
/**
* 创建者
*/
@TableField(fill = FieldFill.INSERT)
private Long createBy;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@TableField(fill = FieldFill.INSERT)
private Date createTime;
/**
* 更新者
*/
@TableField(fill = FieldFill.UPDATE)
private Long updateBy;
/**
* 更新时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@TableField(fill = FieldFill.UPDATE)
private Date updateTime;
/**
* 删除标志(Y-已删除,N-未删除)
*/
@TableLogic
private String delFlag;
/**
* 开始时间
*/
@JsonIgnore
@TableField(exist = false)
private String beginTime;
/**
* 结束时间
*/
@JsonIgnore
@TableField(exist = false)
private String endTime;
}
使用
调用了一个update
方法
postMapper.updatePost(post);
在进行更新操作时,mybatis-plus
会追加where条件防止更新到已删除数据,且使用wrapper.entity
生成的where
条件会忽略该字段。也就是说,我本来的方法对应的sql
可能是
update xx set xx where xx=xx
如果我配置的逻辑删除没有问题的话,mybatis-plus
生成的sql
应该是
update xx set xx where xx=xx and del_flag = 'N'
但是实际我测试发现,生成的sql
却是
update xx set xx where xx=xx and del_flag = '0'
可以看到,虽然逻辑删除的字段是对的,但是实际上,对应字段是否删除的值还是mybatis-plus
默认的,并不是我们设置的。
问题分析
其实这个问题之前还是好的,让我想到应该是最近配置的SqlSessionFactory
的问题。
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
String typeAliasesPackage = env.getProperty("mybatis-plus.typeAliasesPackage");
String mapperLocations = env.getProperty("mybatis-plus.mapperLocations");
String configLocation = env.getProperty("mybatis-plus.configLocation");
typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage);
VFS.addImplClass(SpringBootVFS.class);
final MybatisSqlSessionFactoryBean sessionFactory = new MybatisSqlSessionFactoryBean ();
sessionFactory.setDataSource(dataSource);
sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
sessionFactory.setMapperLocations(resolveMapperLocations(StringUtils.split(mapperLocations, ",")));
sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation));
sessionFactory.setPlugins(mybatisSqlInterceptor(),mybatisPlusInterceptor());
return sessionFactory.getObject();
}
我这里重新注入了MybatisSqlSessionFactoryBean
,但是并没有对它的配置进行修改,这就导致了我配置文件里的东西并没有加载。
解决
解决办法也很简单,两种方式我们分别说下。
方式一
方式一是在我们实体逻辑删除的注解上加上删除和未删除对应的值。
/**
* 删除标志(Y-已删除,N-未删除)
*/
@TableLogic(value = "N",delval = "Y")
private String delFlag;
方式二
方式二就是,我们在MybatisSqlSessionFactoryBean
的bean
里,把我们配置文件里的配置加上。对SqlSessionFactory
改造如下
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
String typeAliasesPackage = env.getProperty("mybatis-plus.typeAliasesPackage");
String mapperLocations = env.getProperty("mybatis-plus.mapperLocations");
String configLocation = env.getProperty("mybatis-plus.configLocation");
typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage);
VFS.addImplClass(SpringBootVFS.class);
final MybatisSqlSessionFactoryBean sessionFactory = new MybatisSqlSessionFactoryBean ();
sessionFactory.setDataSource(dataSource);
sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
sessionFactory.setMapperLocations(resolveMapperLocations(StringUtils.split(mapperLocations, ",")));
sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation));
sessionFactory.setPlugins(mybatisSqlInterceptor(),mybatisPlusInterceptor());
sessionFactory.setGlobalConfig(globalConfig());
return sessionFactory.getObject();
}
@Bean
public MybatisSqlInterceptor mybatisSqlInterceptor() {
MybatisSqlInterceptor mybatisSqlInterceptor = new MybatisSqlInterceptor();
Properties properties = new Properties();
mybatisSqlInterceptor.setProperties(properties);
return mybatisSqlInterceptor;
}
/**
* 逻辑删除插件
*/
@Bean
public GlobalConfig globalConfig() {
GlobalConfig globalConfig = new GlobalConfig();
GlobalConfig.DbConfig dbConfig = new GlobalConfig.DbConfig();
dbConfig.setLogicDeleteValue("Y");
dbConfig.setLogicNotDeleteValue("N");
globalConfig.setDbConfig(dbConfig);
return globalConfig;
}
看看