Skip to content

MyBatis-Plus

常用方法

名称实践问题
@KeySequence主键生成策略,解决新增时id生成问题
@TableId解决实体属性名称与物理表主键字段名称不一致问题
@TableName解决实体名称与表名称不一致问题
@TableField解决实体属性名称与表字段名称不一致问题

@KeySequence

  • 描述:序列主键策略 oracle
  • 属性:value、resultMap
属性类型必须指定默认值描述
valueString""序列名
clazzClassLong.classid的类型, 可以指定String.class,这样返回的Sequence值是字符串"1"

@TableId

  • 描述:主键注解
属性类型必须指定默认值描述
valueString""主键字段名
typeEnumIdType.NONE主键类型
  • IdType
描述
AUTO数据库ID自增
NONE无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)
INPUTinsert前自行set主键值
ASSIGN_ID分配ID(主键类型为Number(Long和Integer)或String)(since 3.3.0),使用接口IdentifierGenerator的方法nextId(默认实现类为DefaultIdentifierGenerator雪花算法)
ASSIGN_UUID分配UUID,主键类型为String(since 3.3.0),使用接口IdentifierGenerator的方法nextUUID(默认default方法)
@TableName
  • 描述:表名注解
属性类型必须指定默认值描述
valueString""表名
schemaString""schema
keepGlobalPrefixbooleanfalse是否保持使用全局的 tablePrefix 的值(如果设置了全局 tablePrefix 且自行设置了 value 的值)
resultMapString""xml 中 resultMap 的 id
autoResultMapbooleanfalse是否自动构建 resultMap 并使用(如果设置 resultMap 则不会进行 resultMap 的自动构建并注入)
excludePropertyString[]{}需要排除的属性名(@since 3.3.1)

条件查询 QueryWrapper

常见问题

注意事项

较为常见的问题为通过mybatis-plus自动生成主键长度为19位的Long类型,而JavaScript中的处理精度为16位,

导致返回给前端后无法根据主键获取到对象。处理方式参考文档地址ID_WORKER 生成主键太长导致 js 精度丢失

代码示例

如果引用Pangea框架封装的mybatis,pom文件中添加依赖

html
<dependency>
    <groupId>com.hisense.pangea</groupId>
    <artifactId>pangea-common-mybatis</artifactId>
    <version>${pangea.version}</version>
</dependency>

参考

常见问题

MyBatis-Plus插入或更新的字段有空字符串或者null

在实际项目中,难免更新的时候,有可能会把已有的值更新成空字符串或者null, 但是当你使用updateById()方法的时候,会发现根本不生效。 这其实是MyBatis-Plus对字段的验证策略导致的,MyBatis-Plus默认进行了不是全量更新的策略, 即:只更新和插入非NULL值

MyBatis-Plus字段验证策略介绍

FieldStrategy 有三种策略:

  • IGNORED:忽略
  • NOT_NULL:非 NULL,默认策略
  • NOT_EMPTY:非空

当用户有更新字段为 空字符串 或者 null 的需求时,需要对 FieldStrategy 策略进行调整:

解决方案

###方案一:全局配置方式(非常不推荐,慎重使用)

在MyBatis-Plus配置文件中修改field-strategy字段验证的值为0,即忽略判断。

xml
mybatis-plus:
  global-config:
    #字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断"
    field-strategy: 0

如果进行如上设置,你会发现更新插入操作的时候会报错:jdbcType不允许为空! 这是因为,一些比如Date等对象类型需指定jdbcType类型。

这个时候,你需要确保实体对象修饰字段的时候,加入jdbcType属性,每个属性对应数据库的jdbcType类型,这样才能成功更新空值或null。如下图:

为什么不推荐全局配置方式

比如我们将一个user表中的 del_flag 设置为1,一般情况我们只需这么做就行:

java
User user = new User();
user.setId(1);
user.setDelFlag(1);
userService.update(user);

这个时候,其实其他的字段都是空,如果他的策略是空更新,那么执行之后,表里就只有id 和del_flag有值,其余的字段都是Null,很明显这不是我们想要的结果,这就是默认的空不更新策略。

###方案二:调整字段验证注解(不推荐)

根据具体情况,在需要更新的字段中调整验证注解,如验证非空:

打开源码可查看,在3.1.2版本后strategy策略的详细描述,如下:

###方案三:使用 UpdateWrapper(推荐)

方案三,也是官网给出的,但是必须要求mp的版本大于3, 如果是3以下的版本没有这个功能,就是使用UpdateWrapper.

比如,我们想把 user表中的email设置为空:

java

mapper.update(
   new User().setName("mp").setAge(3),
   Wrappers.<User>lambdaUpdate()
           .set(User::getEmail, null) //把email设置成null
           .eq(User::getId, 2)
);
//也可以参考下面这种写法
mapper.update(
    null,
    Wrappers.<User>lambdaUpdate()
       .set(User::getAge, 3)
       .set(User::getName, "mp")
       .set(User::getEmail, null) //把email设置成null
       .eq(User::getId, 2)
);