MyBatis-Plus
常用方法
名称 | 实践问题 |
---|---|
@KeySequence | 主键生成策略,解决新增时id生成问题 |
@TableId | 解决实体属性名称与物理表主键字段名称不一致问题 |
@TableName | 解决实体名称与表名称不一致问题 |
@TableField | 解决实体属性名称与表字段名称不一致问题 |
@KeySequence
- 描述:序列主键策略 oracle
- 属性:value、resultMap
属性 | 类型 | 必须指定 | 默认值 | 描述 |
---|---|---|---|---|
value | String | 否 | "" | 序列名 |
clazz | Class | 否 | Long.class | id的类型, 可以指定String.class,这样返回的Sequence值是字符串"1" |
@TableId
- 描述:主键注解
属性 | 类型 | 必须指定 | 默认值 | 描述 |
---|---|---|---|---|
value | String | 否 | "" | 主键字段名 |
type | Enum | 否 | IdType.NONE | 主键类型 |
- IdType
值 | 描述 |
---|---|
AUTO | 数据库ID自增 |
NONE | 无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT) |
INPUT | insert前自行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 |
- 描述:表名注解
属性 | 类型 | 必须指定 | 默认值 | 描述 |
---|---|---|---|---|
value | String | 否 | "" | 表名 |
schema | String | 否 | "" | schema |
keepGlobalPrefix | boolean | 否 | false | 是否保持使用全局的 tablePrefix 的值(如果设置了全局 tablePrefix 且自行设置了 value 的值) |
resultMap | String | 否 | "" | xml 中 resultMap 的 id |
autoResultMap | boolean | 否 | false | 是否自动构建 resultMap 并使用(如果设置 resultMap 则不会进行 resultMap 的自动构建并注入) |
excludeProperty | String[] | 否 | {} | 需要排除的属性名(@since 3.3.1) |
条件查询 QueryWrapper
常见问题
- https://baomidou.com/guide/faq.html 解决排除非表中字段、排除实体父类属性等问题
注意事项
较为常见的问题为通过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)
);