项目场景:
Springboot2+PostgreSQL+MybatisPlus
问题描述
在建立Entity时添加了逻辑删除字段:
java
@Data
public class BaseEntity implements Serializable {
private static final long serialVersionUID = 1L;
// 主键ID
@TableId
private String id;
// 删除标识 (逻辑删除字段)
@TableLogic
@TableField(fill = FieldFill.INSERT) // 默认插入时设置为 false
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
private Boolean deleted = false;
// 创建时间
@TableField(fill = FieldFill.INSERT) // 插入时自动填充
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
private LocalDateTime createTime;
// 更新时间
@TableField(fill = FieldFill.INSERT_UPDATE) // 插入和更新时自动填充
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
private LocalDateTime updateTime;
}
数据表建立:
sql
create table tb_user
(
id varchar(255) not null
primary key,
username varchar(255) not null
unique,
password varchar(255) not null,
deleted boolean default false,
create_time timestamp default CURRENT_TIMESTAMP,
update_time timestamp default CURRENT_TIMESTAMP
);
查询语句:
java
if (userMapper.selectCount(new QueryWrapper<TbUser>()
.eq("username", tbUser.getUsername())) > 0) {
throw new ViewException(ViewExceptionType.DATA_ALREADY_EXISTS, "用户名已存在");
}
随后在插入数据的时候报错:
### Error querying database. Cause: org.postgresql.util.PSQLException: 错误: 操作符不存在: boolean = integer
建议:没有匹配指定名称和参数类型的操作符. 您也许需要增加明确的类型转换.
位置:55
### The error may exist in com/sgcchg/data/mapper/UserMapper.java (best guess)
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: SELECT COUNT( * ) AS total FROM tb_user WHERE deleted=0 AND (username = ?)
### Cause: org.postgresql.util.PSQLException: 错误: 操作符不存在: boolean = integer
建议:没有匹配指定名称和参数类型的操作符. 您也许需要增加明确的类型转换.
位置:55
; bad SQL grammar []; nested exception is org.postgresql.util.PSQLException: 错误: 操作符不存在: boolean = integer
建议:没有匹配指定名称和参数类型的操作符. 您也许需要增加明确的类型转换.
位置:55
org.springframework.jdbc.BadSqlGrammarException:
### Error querying database. Cause: org.postgresql.util.PSQLException: 错误: 操作符不存在: boolean = integer
建议:没有匹配指定名称和参数类型的操作符. 您也许需要增加明确的类型转换.
位置:55
### The error may exist in com/sgcchg/data/mapper/UserMapper.java (best guess)
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: SELECT COUNT( * ) AS total FROM tb_user WHERE deleted=0 AND (username = ?)
### Cause: org.postgresql.util.PSQLException: 错误: 操作符不存在: boolean = integer
建议:没有匹配指定名称和参数类型的操作符. 您也许需要增加明确的类型转换.
位置:55
; bad SQL grammar []; nested exception is org.postgresql.util.PSQLException: 错误: 操作符不存在: boolean = integer
建议:没有匹配指定名称和参数类型的操作符. 您也许需要增加明确的类型转换.
位置:55
at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:101) ~[spring-jdbc-5.3.22.jar:5.3.22]
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:70) ~[spring-jdbc-5.3.22.jar:5.3.22]
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:79) ~[spring-jdbc-5.3.22.jar:5.3.22]
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:79) ~[spring-jdbc-5.3.22.jar:5.3.22]
at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:92) ~[mybatis-spring-2.1.2.jar:2.1.2]
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) ~[mybatis-spring-2.1.2.jar:2.1.2]
at com.sun.proxy.$Proxy98.selectOne(Unknown Source) ~[na:na]
at org.mybatis.spring.SqlSessionTemplate.selectOne(SqlSessionTemplate.java:160) ~[mybatis-spring-2.1.2.jar:2.1.2]
at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.execute(MybatisMapperMethod.java:87) ~[mybatis-plus-core-3.5.5.jar:3.5.5]
at com.baomidou.mybatisplus.core.override.MybatisMapperProxy$PlainMethodInvoker.invoke(MybatisMapperProxy.java:152) ~[mybatis-plus-core-3.5.5.jar:3.5.5]
at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:89) ~[mybatis-plus-core-3.5.5.jar:3.5.5]
at com.sun.proxy.$Proxy106.selectCount(Unknown Source) ~[na:na]
at com.sgcchg.business.impl.user.UserServiceImpl.addUser(UserServiceImpl.java:72) ~[classes/:na]
原因分析:
数据库字段是boolean。但是在wrapper查询的时候没有指定deleted,查看报错信息发现最终底层查询会有deleted=0。
原因为:MyBatis-Plus 提供了逻辑删除功能,可以自动在查询条件中添加逻辑删除字段的判断条件。如果 deleted 字段被配置为逻辑删除字段,那么 MyBatis-Plus 在查询时会自动将 deleted = false 这个条件添加到查询语句中。
解决方案:
在 application.yml 或 application.properties中进行以下配置:
bash
mybatis-plus:
global-config:
db-config:
logic-delete-field: deleted # 逻辑删除字段名
logic-not-delete-value: 0 # 表示未删除的值
logic-delete-value: 1 # 表示已删除的值
或
bash
mybatis-plus.global-config.db-config.logic-delete-field=deleted
mybatis-plus.global-config.db-config.logic-delete-value=true
mybatis-plus.global-config.db-config.logic-not-delete-value=false
即可解决
还有一种方法是修改配置文件:
java
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 配置逻辑删除
LogicSqlInjector logicSqlInjector = new LogicSqlInjector();
interceptor.addInnerInterceptor(logicSqlInjector);
return interceptor;
}
@Bean
public ConfigurationCustomizer configurationCustomizer() {
return configuration -> configuration.setObjectWrapperFactory(new DefaultObjectWrapperFactory() {
@Override
public boolean hasWrapperFor(Object object) {
return object instanceof Boolean;
}
@Override
public ObjectWrapper getWrapperFor(MetaObject metaObject, Object object) {
return new BooleanObjectWrapper(metaObject, (Boolean) object);
}
});
}
}