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);
            }
        });
    }
}
相关推荐
Yaml433 分钟前
Spring Boot 与 Vue 共筑二手书籍交易卓越平台
java·spring boot·后端·mysql·spring·vue·二手书籍
小小小妮子~34 分钟前
Spring Boot详解:从入门到精通
java·spring boot·后端
hong16168836 分钟前
Spring Boot中实现多数据源连接和切换的方案
java·spring boot·后端
Channing Lewis40 分钟前
salesforce case可以新建一个roll up 字段,统计出这个case下的email数量吗
数据库·salesforce
aloha_7891 小时前
从零记录搭建一个干净的mybatis环境
java·笔记·spring·spring cloud·maven·mybatis·springboot
记录成长java2 小时前
ServletContext,Cookie,HttpSession的使用
java·开发语言·servlet
睡觉谁叫~~~2 小时前
一文解秘Rust如何与Java互操作
java·开发语言·后端·rust
毕业设计制作和分享2 小时前
ssm《数据库系统原理》课程平台的设计与实现+vue
前端·数据库·vue.js·oracle·mybatis
ketil272 小时前
Redis - String 字符串
数据库·redis·缓存
程序媛小果2 小时前
基于java+SpringBoot+Vue的旅游管理系统设计与实现
java·vue.js·spring boot