最近在使用Mybatis-plus发现一个很奇怪的现象,明明用的Mybatis-plus里面的deleteById,但是数据库里却是逻辑删除,去研究了一下Mybatis-plus的配置才弄明白
SqlHelper.retBool()方法是判断数据库操作是否成功
走到这里,其实按照正常逻辑来说,数据库里执行的应该是
delete from 表名 where id = #{id}
这样的一个sql语句,是物理删除而不是逻辑删除,但是数据库里最后执行的却是逻辑删除,所以我找到了配置文件application.yml
# mybatis
mybatis-plus:
mapper-locations: classpath:/mappers/**/*Mapper.xml
global-config:
#刷新mapper 调试神器
db-config:
#主键类型 0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";
id-type: auto
#字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断"
field-strategy: not_empty
column-underline: true
db-type: mysql
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
configuration:
cache-enabled: false
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
jackson:
date-format: java.text.SimpleDateFormat #或正则yyyy-MM-dd HH:mm:ss
time-zone: GMT+8 #或UTC
从这里可以看出,配置了很多东西
比如配置了Mapper.xml的路径,只有在这个路径下的Mapper.xml,Mybatis-plus才可以识别到
还配置了主键类型,可以看到我们这里配置的是auto,点进去就可以看到
说明我们设置的是数据库主键自增
然后下一个配置是字段策略
mybatis-plus:
global-config:
db-config:
field-strategy:
IGNORED (忽略 如果字段是null,就用null更新)
not_null (不为null, 当字段是null时,就忽略这个字段的更新)
not_empty (不为null和‘’, 当字段是null或者是空时,忽略这个字段的更新)
接下来是column-underline
这个配置,它是驼峰和下划线的转换策略,设置为true就是开启
至于db-type: mysql
这个配置就很好理解了,你数据库用的mysql就写mysql,用的oracle就写oracle,没啥好说的
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
这两个配置就是逻辑删除了,也就是我之前的疑惑的源头,就是在这里配置以后就可以设置逻辑已删除为1,逻辑未删除为0
除了这个配置还在实体类中也有注解配合,以我项目中使用方法为例
首先将一些各个表比较通用的字段建实体类,比如id啊,状态啊之类的
可以看到在状态上有一个注解@TableLogic
,这个注解注释的字段,就是配合配置文件中配置的逻辑删除字段
@Data
public class BaseModel {
/**
* 主键id
*/
@ApiModelProperty(hidden = true,value = "主键id")
@ExcelIgnore
private Integer id;
/**
* 逻辑删除 0未删除 1已删除
*/
@TableLogic
@JsonIgnore
@ApiModelProperty(hidden = true)
@ExcelIgnore
private String delStatus;
/**
* 建档时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(hidden = true)
@ExcelProperty(value = "创建时间",index = 3)
@ColumnWidth(20)
private Date createTime;
/**
* 创建人
*/
@ApiModelProperty(hidden = true,value = "创建人")
@ExcelIgnore
private String createBy;
/**
* 修改日期
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(hidden = true,value = "修改时间")
@ExcelIgnore
private Date updateTime;
/**
* 修改人
*/
@ApiModelProperty(hidden = true,value = "修改人")
@ExcelIgnore
private String updateBy;
/**
* 备注
*/
@ApiModelProperty(value = "备注")
@TableField(updateStrategy = FieldStrategy.NOT_NULL, jdbcType = JdbcType.NUMERIC)
@ExcelIgnore
private String remark;
}
然后根据不同的表再创建不同的实体类,继承这个公共的实体类就好
比如person_info,用户信息表
//根据子类自身的字段值和从父类继承的字段值 来生成hashcode,当两个子类对象比较时,只有子类对象的本身的字段值和继承父类的字段值都相同,equals方法的返回值是true。
@EqualsAndHashCode(callSuper = true)
@Data
@TableName("person_info")
public class PersonInfo extends BaseModel {
@ApiModelProperty("人员姓名")
private String personName;
@ApiModelProperty("身份证")
private String idCard;
.
.
.
}
这个实体类里面就可以只写这个表特有的字段,@TableName
注解后面加对应的表名
配置文件里面的cache-enabled: false
这个配置就很简单了,禁用二级缓存
再下面就是配置时间了
除了这个有配置,还要进行Mybatis-plus配置
/**
* MybatisPlus 配置
*/
//开始数据库事务
@EnableTransactionManagement
@Configuration
//扫描指定路径下的mapper接口
@MapperScan(basePackages = {"xxx.mapper","xxx.mapper"})
public class MybatisPlusConfig {
/**
* mybatis-plus分页插件<br>
* 文档:http://mp.baomidou.com<br>
*/
@Bean(name = "pagination")
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
return paginationInterceptor;
}
@Bean
public ISqlInjector sqlInjector() {
// return new LogicSqlInjector();
return new DefaultSqlInjector();
}
}
分页插件就没啥好说的了,直接用的Mybatis-plus的分页拦截器
Mybatis-plus也有分页Page对象接口,直接用就完事了
再下面的那个方法其实是使用sql注入器
使用SQL注入器,通常是使用自定义Mapper(MyBaseMapper)接口继承BaseMapper接口,我们自定义的方法就写在MyBaseMapper里。然后我们业务相关的Mapper继承MyBaseMapper就都可以使用该方法。这一切只需要我们自定义一个SQL模板,注入到MP即可,而不是换一个表就得重写一个xml