PostgreSQL+MybatisPlus,设置逻辑删除字段后查询出现:操作符不存在: boolean = integer 错误

项目场景:

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);
            }
        });
    }
}
相关推荐
瓯雅爱分享3 小时前
Java+Vue构建的采购招投标一体化管理系统,集成招标计划、投标审核、在线竞价、中标公示及合同跟踪功能,附完整源码,助力企业实现采购全流程自动化与规范化
java·mysql·vue·软件工程·源代码管理
BTU_YC5 小时前
Neo4j查询计划完全指南:读懂数据库的“执行蓝图“
数据库·neo4j
非极限码农5 小时前
Neo4j图数据库上手指南
大数据·数据库·数据分析·neo4j
mit6.8246 小时前
[C# starter-kit] 命令/查询职责分离CQRS | MediatR |
java·数据库·c#
诸神缄默不语6 小时前
Maven用户设置文件(settings.xml)配置指南
xml·java·maven
任子菲阳6 小时前
学Java第三十四天-----抽象类和抽象方法
java·开发语言
苏打水com6 小时前
数据库进阶实战:从性能优化到分布式架构的核心突破
数据库·后端
学Linux的语莫7 小时前
机器学习数据处理
java·算法·机器学习
找不到、了7 小时前
JVM的即时编译JIT的介绍
java·jvm
shan~~7 小时前
linux达梦数据库操作
linux·数据库·chrome