Mybatis Plus快速入门(二)
5.注解
下面是一些常用注解,更多注解可以查看官网。
- @TableName 表名注解,标识实体类对应的表
- @TableId 主键注解
- @TableField 字段注解(非主键)
- @TableLogic 表字段逻辑处理注解
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 方法) |
ID_WORKER | 分布式全局唯一 ID 长整型类型(please use ASSIGN_ID ) |
UUID | 32 位 UUID 字符串(please use ASSIGN_UUID ) |
ID_WORKER_STR | 分布式全局唯一 ID 字符串类型(please use ASSIGN_ID ) |
6.前后端分离项目约定
我们在正式开始我们的模块测试之前先进行一些项目中的约定,定义后端返回给前端的统一格式,异常统一处理格式。
6.1 后端返回前端数据格式
@ApiModel("返回状态码对象")
public enum ResultCode {
/***
* 成功
*/
SUCCESS(200, "成功"),
/***
* 参数错误
*/
PARAM_ERROR(201,"参数错误"),
/***
* 未找到资源
*/
NOT_FOUND(404,"未找到资源"),
/***
* 服务器错误
*/
FAIL(500,"服务器错误");
@Getter
@ApiModelProperty("返回状态码")
private final int code;
@Getter
@ApiModelProperty("返回信息")
private final String message;
ResultCode(int code,String message){
this.code = code;
this.message = message;
}
}
@Data
@ApiModel("后端返回前端统一格式")
public class ResponseResult<T> implements Serializable {
@ApiModelProperty("是否返回成功")
private Boolean success;
@ApiModelProperty("状态码")
private Integer code;
@ApiModelProperty("描述")
private String message;
@ApiModelProperty("返回数据")
private T data;
@ApiModelProperty("时间戳")
private Long timestamp;
public ResponseResult(){
this.timestamp = System.currentTimeMillis();
}
/***
* 返回成功
* @param code 状态码
* @param message 消息
* @param data 数据
* @return 返回前端信息
* @author 无涯子
* @date 2024/4/14 17:37:19
*/
public static <T> ResponseResult<T> success(int code,String message,T data){
ResponseResult<T> responseResult = new ResponseResult<>();
responseResult.setSuccess(true);
responseResult.setCode(code);
responseResult.setMessage(message);
responseResult.setData(data);
return responseResult;
}
/***
* 返回成功
* @param code 状态码
* @param message 消息
* @return 返回前端信息
* @author 无涯子
* @date 2024/4/14 17:40:44
*/
public static <T> ResponseResult<T> success(int code,String message) {
return success(code, message, null);
}
/***
* 返回成功
* @param message 消息
* @param data 数据
* @return 返回前端信息
* @author 无涯子
* @date 2024/4/14 17:47:54
*/
public static <T> ResponseResult<T> success(String message,T data) {
return success(ResultCode.SUCCESS.getCode(), message, data);
}
/***
* 返回成功
* @param message 消息
* @return 返回前端信息
* @author 无涯子
* @date 2024/4/14 17:46:48
*/
public static <T> ResponseResult<T> success(String message) {
return success(message, null);
}
/***
* 返回成功
* @param data 数据
* @return 返回前端信息
* @author 无涯子
* @date 2024/4/14 17:45:23
*/
public static <T> ResponseResult<T> success(T data) {
return success(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMessage(), data);
}
/***
* 返回成功
* @return 返回前端信息
* @author 无涯子
* @date 2024/4/14 17:43:44
*/
public static <T> ResponseResult<T> success() {
return success(null);
}
/***
* 返回失败
* @param code 状态码
* @param message 消息
* @param data 数据
* @return 返回前端信息
* @author 无涯子
* @date 2024/4/14 17:49:28
*/
public static <T> ResponseResult<T> fail(int code,String message,T data){
ResponseResult<T> responseResult = new ResponseResult<>();
responseResult.setSuccess(false);
responseResult.setCode(code);
responseResult.setMessage(message);
responseResult.setData(data);
return responseResult;
}
/***
* 返回失败
* @param code 状态码
* @param message 消息
* @return 返回前端信息
* @author 无涯子
* @date 2024/4/14 17:49:28
*/
public static <T> ResponseResult<T> fail(int code,String message){
return fail(code, message, null);
}
/***
* 返回失败
* @param message 消息
* @param data 数据
* @return 返回前端信息
* @author 无涯子
* @date 2024/4/14 17:49:28
*/
public static <T> ResponseResult<T> fail(String message,T data){
return fail(ResultCode.FAIL.getCode(), message, data);
}
/***
* 返回失败
* @param message 消息
* @return 返回前端信息
* @author 无涯子
* @date 2024/4/14 17:49:28
*/
public static <T> ResponseResult<T> fail(String message){
return fail(ResultCode.FAIL.getCode(), message, null);
}
/***
* 返回失败
* @return 返回前端信息
* @author 无涯子
* @date 2024/4/14 17:49:28
*/
public static <T> ResponseResult<T> fail(){
return fail(ResultCode.FAIL.getMessage());
}
}
6.2异常处理
@Getter
public class AppException extends RuntimeException{
private static final long serialVersionUID = -7611643172712984323L;
private String code = ResultCode.FAIL.getCode() + "";
public AppException() {
super();
}
public AppException(final String code ,final String message){
super(message);
this.code = code;
}
public AppException(final String code ,final String message,final Throwable cause){
super(message, cause);
this.code = code;
}
public AppException(final String message){
super(message);
}
public AppException(final String message, final Throwable cause) {
super(message, cause);
}
public AppException(final Throwable cause) {
super(cause);
}
public AppException(ResultCode resultCode, Object... args) {
super(MessageFormat.format(resultCode.getMessage(), args));
this.code = resultCode.getCode() + "";
}
}
6.3数据转换工具
public class ConvertUtil {
private ConvertUtil(){
}
public static <T, R> Page<R> convert(Page<T> source, Function<T, R> converter) {
List<R> records = source.getRecords().stream().map(converter).collect(Collectors.toList());
Page page = new Page<>(source.getCurrent(), source.getSize(), source.getTotal());
page.setRecords(records);
return page;
}
public static <T, R> List<R> convertList(List<T> source, Function<T, R> converter) {
return source.stream().map(converter).collect(Collectors.toList());
}
}
6.4 模块结构
controller:控制层
entity:实体类
mapper:数据库映射
model:model对象
convert: 转换类
dto: 前后端传递数据对象
vo:前端显示对象
query:查询
service:核心业务层
util:工具
config:配置相关
7.CURD快速入门
使用Mybtais Plus
进行CURD,有两种实现方式,我们这里使用基于Mapper接口的实现,Service接口方式跟这种方式大同小异。测试我们使用Postman进行。
7.1 Service层
@Service
public class UserServiceImpl implements UserService {
@Resource
private UserMapper userMapper;
@Resource
private UserConvert userConvert;
/**
* 新增用户
* @param userDTO 用户数据
*/
@Override
public void saveUser(UserDTO userDTO) {
UserDO userDO = userConvert.toDO(userDTO);
userMapper.insert(userDO);
}
/**
* 删除用户
* @param id 用户ID
*/
@Override
public void deleteUserById(Long id) throws AppException{
int i = userMapper.deleteById(id);
if(i != 1) {
throw new AppException("删除用户失败");
}
}
/**
* 更新用户信息根据ID
* @param userDTO 用户数据
*/
@Override
public void updateUserById(UserDTO userDTO) {
UserDO userDO = userConvert.toDO(userDTO);
userMapper.updateById(userDO);
}
/**
* 根据用户ID查询用户信息
* @param id 用户ID
* @return 用户信息
*/
@Override
public UserVO queryUserById(Long id) {
return userConvert.toVO(userMapper.selectById(id));
}
/**
* 查询所有用户信息
* @return 用户信息
*/
@Override
public List<UserVO> queryUserAll() {
List<UserDO> userList = userMapper.selectList(null);
return ConvertUtil.convertList(userList,userConvert::toVO);
}
/**
* 分页查询
* @param current 当前页
* @param size 页大小
* @return 分页数据
*/
@Override
public Page<UserVO> queryUserPage(Integer current, Integer size) {
Page<UserDO> page = new Page<>();
page.setCurrent(current);
page.setSize(size);
Page<UserDO> userPage = userMapper.selectPage(page, null);
return ConvertUtil.convert(userPage, userConvert::toVO);
}
/**
* 根据条件查询用户信息
* @param userQuery 查询条件
* @return 用户信息
*/
@Override
public List<UserVO> queryUser(UserQuery userQuery) {
LambdaQueryWrapper<UserDO> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(StrUtil.isNotBlank(userQuery.getName()),UserDO::getName, userQuery.getName())
.eq(userQuery.getAge() != null,UserDO::getAge,userQuery.getAge())
.eq(StrUtil.isNotBlank(userQuery.getEmail()),UserDO::getEmail,userQuery.getEmail());
List<UserDO> userList = userMapper.selectList(queryWrapper);
return ConvertUtil.convertList(userList,userConvert::toVO);
}
}
7.2 Model对象
@Data
public class UserVO {
@ApiModelProperty("用户ID")
private Long id;
@ApiModelProperty(value = "姓名")
private String name;
@ApiModelProperty(value = "年龄")
private Integer age;
@ApiModelProperty(value = "电子邮箱地址")
private String email;
}
@Data
public class UserQuery {
@ApiModelProperty(value = "姓名")
private String name;
@ApiModelProperty(value = "年龄")
private Integer age;
@ApiModelProperty(value = "电子邮箱地址")
private String email;
}
@Data
public class UserDTO {
@ApiModelProperty("用户ID")
private Long id;
@ApiModelProperty(value = "姓名")
@NotBlank(message = "姓名不能为空")
private String name;
@ApiModelProperty(value = "年龄")
@NotNull(message = "年龄不能为空")
private Integer age;
@NotBlank(message = "电子邮箱地址不能为空")
@ApiModelProperty(value = "电子邮箱地址")
private String email;
}
@Mapper(componentModel = "Spring")
public interface UserConvert {
/**
* DO转VO
* @param userDO DO
* @return VO
*/
UserVO toVO(UserDO userDO);
/**
* DO转VO
* @param userDTO DTO
* @return DO
*/
UserDO toDO(UserDTO userDTO);
}
7.3 Controller
@RestController
@RequestMapping("/user")
public class UserController {
@Resource
private UserService userService;
@ApiOperation("保存用户信息")
@PostMapping
public ResponseResult<String> saveUser(@RequestBody @Validated UserDTO userDTO){
userService.saveUser(userDTO);
return ResponseResult.success();
}
@DeleteMapping("/{id}")
@ApiOperation("删除用户信息")
public ResponseResult<String> deleteUserById(@Validated @NotNull(message = "ID不能为空") @PathVariable Long id) throws AppException {
userService.deleteUserById(id);
return ResponseResult.success();
}
@PutMapping
@ApiOperation("更新用户信息")
public ResponseResult<String> updateUserById(@RequestBody @Validated UserDTO userDTO){
userService.updateUserById(userDTO);
return ResponseResult.success();
}
@GetMapping("/{id}")
@ApiOperation("根据ID查询用户信息")
public ResponseResult<UserVO> queryUserById(@Validated @NotNull(message = "ID不能为空") @PathVariable Long id){
return ResponseResult.success(userService.queryUserById(id));
}
@GetMapping
@ApiOperation("查询所有用户信息")
public ResponseResult<List<UserVO>> queryUserAll(){
return ResponseResult.success(userService.queryUserAll());
}
@GetMapping("/{current}/{size}")
@ApiOperation("分页查询")
public ResponseResult<Page<UserVO>> queryUserPage(@Validated @NotNull(message = "当前页不能为空") @PathVariable
Integer current,
@NotNull(message = "页大小不能为空") @PathVariable Integer size){
return ResponseResult.success(userService.queryUserPage(current,size));
}
@GetMapping("/query")
@ApiOperation("条件查询")
public ResponseResult<List<UserVO>> queryUser(UserQuery userQuery){
return ResponseResult.success(userService.queryUser(userQuery));
}
}
7.4 Mybatis Plus分页配置
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return mybatisPlusInterceptor;
}
}
7.5 Postman测试