枚举类是开发时绕不开的话题, Mybatis-Plus 也提供了简便的枚举功能,快学起来吧~
目录
源码地址:尹煜 / mybatis_plus_study · GitCode
1 版本区别
其实 Mybatis-Plus 不同的版本,通用枚举配置是不一样的,稍早一些的需要实现 IEnum 接口,并且需要在配置文件中配置 typeEnumsPackage 或者编写配置类,这难免有些复杂(详情见https://baomidou.com/pages/8390a4/)。
而 Mybatis-Plus 从 3.5.2 版本开始只需使用 @EnumValue 注解枚举属性,简单来说就是一个注解解决了一系列配置,本文也将讲解 @EnumValue 注解枚举属性这种方式!
所用到的依赖 👇,web 依赖会在后边用到。
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2 通用枚举功能实现
2.1 创建枚举类
路径:src\main\java\com\yinyu\enums\CheckEnum.java
该枚举类以数字作为媒介,也就是说数据库里存的是数字。
package com.yinyu.enums;
import com.baomidou.mybatisplus.annotation.EnumValue;
import com.fasterxml.jackson.annotation.JsonValue;
import lombok.Getter;
@Getter //构建get方法
public enum CheckEnum {
//未审核
NULL(0, "未审核"),
//审核不通过
FAIL(1, "审核不通过"),
//审核通过
SUCCESS(2, "审核通过");
@EnumValue//标记数据库存的值是code
private final int code;
@JsonValue //前端展示
private final String text;
CheckEnum(int code, String text) {
this.code = code;
this.text = text;
}
}
2.2 实体类新增枚举字段
首先确保数据表里存在该字段 👇
然后给实体类新增 isCheck 枚举字段
路径:src/main/java/com/yinyu/pojo/User.java
package com.yinyu.pojo;
import com.baomidou.mybatisplus.annotation.*;
import com.yinyu.enums.CheckEnum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private Integer age;
private String email;
//枚举字段
private CheckEnum isCheck;
@Version//乐观锁version注解
private Integer version;
@TableLogic//逻辑删除注解
private Integer deleted;
//字段 字段添加填充内容
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
}
若涉及到 xxMapper.xml,也需要添加该字段信息,字段类型依旧是数字,如下:
<result property="isCheck" column="is_check" jdbcType="INTEGER"/>
3 枚举字段测试
路径:src/test/java/com/yinyu/EnumTest.java
3.1 新增
① 后台指定枚举
测试以下三种情况:不指定枚举默认保存、指定枚举默认保存和 userMapper.insert 保存👇
@Test
public void testSave1() {
User user = new User();
user.setName("testSave1");
user.setAge(17);
user.setEmail("yinyu@161.com");
// 不指定枚举默认保存
userService.save(user);
}
@Test
public void testSave2() {
User user = new User();
user.setName("testSave2");
user.setAge(18);
user.setEmail("yinyu@162.com");
user.setIsCheck(CheckEnum.SUCCESS);
// 指定枚举默认保存
userService.save(user);
}
@Test
public void testSave3() {
User user = new User();
user.setName("testSave3");
user.setAge(19);
user.setEmail("yinyu@163.com");
user.setIsCheck(CheckEnum.FAIL);
// userMapper.insert保存
userMapper.insert(user);
}
结果如下 👇,新增成功,能够按照枚举类型往数据表里添加信息
② 前后端交互
那么前后端交互时如何使用这个枚举字段呢,请看下文:
📌 首先建一个简单的对外接口 Controller ,然后添加保存接口👇
路径:src/main/java/com/yinyu/controller/UserController.java
package com.yinyu.controller;
import com.yinyu.pojo.User;
import com.yinyu.service.impl.UserServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("api/user")
public class UserController {
@Autowired
private UserServiceImpl userService;
@PostMapping("/save")
public boolean save(@RequestBody User user) {
return userService.save(user);
}
}
📌 请求该接口
此时需要在 application.properties 配置文件中加上项目端口:
server.port=8080
server.error.include-message=always
然后启动项目,使用 API 工具请求该接口 👇,isCheck 字段使用其描述来匹配枚举类型,建议使用该种方式。
除了 "isCheck": "审核不通过","isCheck": 1 也能达到相同的效果,需要注意的是:"isCheck": 1 对枚举类的要求苛刻,需要保证枚举数字从0开始并按顺序排列,因为它是按顺序取枚举的(可忽略该种方式)。
结果 👇,新增成功,虽然请求体中的 isCheck 字段是字符串,但是数据表存储的是数字。
3.2 查询
测试以下三种情况:直接根据 id 查询和使用 wrapper 查询
@Test
public void testQuery1() {
// 根据id请求
User user = userService.getById(9);
System.out.println(user);
}
@Test
public void testQuery2() {
// 根据wrapper请求,指定枚举类型
LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(User::getIsCheck, CheckEnum.FAIL);
List<User> result = userService.list(wrapper);
System.out.println(result);
}
testQuery2 的结果如下 👇,查询后会将 isCheck 的结果反显成其描述,这就是 @JsonValue 注解的作用。
3.3 修改
① 后台指定枚举
后台修改的话主要有以下两种方式,我一般都用第二种 👇
@Test
public void testUpdate1() {
// 修改 id=9 记录的 is_ischeck,需要指定id才可以更新
User user = new User();
user.setId(9L);
user.setIsCheck(CheckEnum.SUCCESS);
boolean result = userService.updateById(user);
System.out.println(result);
}
@Test
public void testUpdate2() {
// 修改 name为 save4记录的 is_ischeck,使用 updateWrapper
LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(User::getName, "save4") //匹配记录
.set(User::getIsCheck, CheckEnum.SUCCESS); //更新字段值
boolean result = userService.update(updateWrapper);
System.out.println(result);
}
② 前后端交互
修改也存在前后端交互的问题:
📌 在 Controller 中添加更新接口
路径:src/main/java/com/yinyu/controller/UserController.java
@PostMapping("/update")
public boolean update(@RequestBody User user) {
return userService.updateById(user);
}
📌 请求该接口
和新增的交互类似,添加完接口后启动项目便可使用 API 工具请求了
可以看到,修改也可以通过字符串匹配枚举类型,也推荐该种方式~
除了 "isCheck": "审核通过","isCheck": 2 也能达到相同的效果,需要注意的是:"isCheck": 1 对枚举类的要求苛刻,需要保证枚举数字从0开始并按顺序排列,因为它是按顺序取枚举的(可忽略该种方式)。
3.4 删除
一般来说是根据 id 进行删除 👇
@Test
public void testRemove1() {
// 根据id删除
boolean result = userService.removeById(8);
System.out.println(result);
}
@Test
public void testRemove2() {
User user = new User();
user.setId(8L); //需要指定id
boolean result = userService.removeById(user);
System.out.println(result);
}
而 wrapper 能够实现根据字段来进行删除对应记录,比如我想把审核通过的记录都删除 👇
@Test
public void testRemove3() {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getIsCheck, CheckEnum.SUCCESS);
boolean result = userService.removeById(wrapper);
System.out.println(result);
}
sql 如下,匹配成功 👇
删除成功 👇