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测试



posted @ 2024-04-30 14:20  无涯子wyz  阅读(47)  评论(0)    收藏  举报