MybatisPlus的扩展功能

MyBatis-Plus作为MyBatis的增强工具,提供了代码生成器、插件扩展、静态工具类、枚举类型转换器及JSON类型处理器等增强功能。代码生成器可根据数据库表自动生成实体类、Mapper、Service等代码,提高开发效率。插件如分页插件简化了分页操作。静态工具类如LambdaQueryWrapper支持链式调用和条件构造。枚举类型转换器使得数据库与Java枚举类型间的数据映射更加便捷。JSON类型处理器则允许直接处理JSON格式数据,增强了数据交互的灵活性。这些功能在项目中分别针对不同场景提供支持,是提升开发效率和代码质量的重要工具。


目录

代码生成

安装插件

使用步骤

静态工具

枚举类型转换器

JSON类型处理器


代码生成

由上篇可知,MybatisPlus基础的**MapperServicePo**代码相对固定,没有什么技术含量。

推荐大家使用一款**MybatisPlus** 的插件,它可以基于图形化界面完成MybatisPlus的代码生成,非常简单。(就是帮助搭建一个架子,可以让咱们更专注于业务层的逻辑)

安装插件

Idea的plugins市场中搜索并安装**MyBatisPlus**插件:

使用步骤

当你重启idea开始使用时,点击Other

点击Config Database,填写对应信息即可。

点击Code Generator,选中要生成的表,填写配置即可。(module是你的子模块,没有就不用填写)

效果如下:

Address实体类

AddressServiceImpI

代码架子生成成功

静态工具

场景描述:实现一个功能,根据一批用户的ID快速查询这些用户的基本信息以及他们的地址详情。

UserVO如下:

java 复制代码
package com.itheima.mp.domain.vo;

import com.itheima.mp.domain.po.UserInfo;
import com.itheima.mp.enums.UserStatus;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.util.List;

@Data
@ApiModel(description = "用户VO实体")
public class UserVO {

    @ApiModelProperty("用户id")
    private Long id;

    @ApiModelProperty("用户名")
    private String username;

    @ApiModelProperty("详细信息")
    private UserInfo info;

    @ApiModelProperty("使用状态(1正常 2冻结)")
    private UserStatus status;

    @ApiModelProperty("账户余额")
    private Integer balance;

    @ApiModelProperty("用户的收货地址")
    private List<AddressVO> addresses;
}

AddressVO如下:

java 复制代码
package com.itheima.mp.domain.vo;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

/**
 * <p>
 * 
 * </p>
 *
 * @author 虎哥
 * @since 2023-07-01
 */
@Data
@ApiModel(description = "收货地址VO")
public class AddressVO{

    @ApiModelProperty("id")
    private Long id;

    @ApiModelProperty("用户ID")
    private Long userId;

    @ApiModelProperty("省")
    private String province;

    @ApiModelProperty("市")
    private String city;

    @ApiModelProperty("县/区")
    private String town;

    @ApiModelProperty("手机")
    private String mobile;

    @ApiModelProperty("详细地址")
    private String street;

    @ApiModelProperty("联系人")
    private String contact;

    @ApiModelProperty("是否是默认 1默认 0否")
    private Boolean isDefault;

    @ApiModelProperty("备注")
    private String notes;
}

问题:Service之间会相互调用,如何解决循环依赖?

具体要求如下:

  1. 查询用户:首先根据传入的一批用户ID集合查询用户的基本信息。如果查询结果为空,则直接返回空列表。
  2. 查询地址:对于查询到的每个用户,根据其ID进一步查询该用户的地址信息。
  3. 数据转换:将查询到的原始地址实体转换为视图对象(VO),以便于前端展示。
  4. 数据整理:按照用户ID对地址信息进行分类整理,确保同一用户的所有地址被归类在一起。
  5. 组装结果:将用户基本信息与对应的地址列表组合起来,形成最终的视图对象(VO)返回给调用方。

解决方案:MybatisPlus提供一个静态工具类:Db。

java 复制代码
    public List<UserVO> queryUserAndAddressByIds(List<Long> ids){
        // 1.查询用户
        List<User> users = listByIds(ids);
        if (CollUtil.isEmpty(users)) {
            return Collections.emptyList();
        }
        // 2.查询地址
        // 2.1 查询用户id集合
        List<Long> userIds = users.stream().map(User::getId).collect(Collectors.toList());
        // 2.2 根据用户id查询地址
        List<Address> addresses = Db.lambdaQuery(Address.class).in(Address::getUserId, userIds).list();
        // 2.3 得到AddressVO集合
        List<AddressVO> addressVOList = BeanUtil.copyToList(addresses, AddressVO.class);
        // 2.4 将对应用户地址分类,相同用户放入同一集合
        Map<Long, List<AddressVO>> addressMap = new HashMap<>(0);
        if (CollUtil.isNotEmpty(addressVOList)) {
            addressMap = addressVOList.stream().collect(Collectors.groupingBy(AddressVO::getUserId));
        }
        // 3.转换VO返回
        List<UserVO> list = new ArrayList<>(users.size());
        for (User user : users) {
            //3.1 转换User的Po为VO
            UserVO vo = BeanUtil.copyProperties(user, UserVO.class);
            //添加
            list.add(vo);
            //加入地址
            vo.setAddresses(addressMap.get(user.getId()));
        }
        return list;
    }

在查询地址时,我们采用了Db的静态方法,因此避免了注入AddressService,减少了循环依赖的风险。(为了将用户集合转为用户id集合,以及将相同用户放入同一集合中,采用了stream流)

枚举类型转换器

User类中有一个用户状态字段,数据库采用的是int类型,对应的PO也是Integer。因此业务操作时必须手动把枚举Integer转换。

定义枚举

java 复制代码
public enum UserStatus {
    NORMAL (1,"正常"),
    FROZEN (2,"冻结"),
    ;

 
    private final int value;

    private final String desc;

    UserStatus(int value, String desc) {
        this.value = value;
        this.desc = desc;
    }
}

User类中的status字段改为UserStatus 类型

把**@EnumValue**注解来标记枚举属性

把@JsonValue注解标记JSON序列化时展示的字段

java 复制代码
public enum UserStatus {
    NORMAL (1,"正常"),
    FROZEN (2,"冻结"),
    ;

    @EnumValue
    private final int value;
    @JsonValue
    private final String desc;

    UserStatus(int value, String desc) {
        this.value = value;
        this.desc = desc;
    }
}

配置枚举处理器

java 复制代码
mybatis-plus:
  configuration:
    default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler

使用swagger框架集成的页面测试

JSON 类型处理器

数据库的user表中有一个info字段,是JSON类型,而目前User实体类中却是String类型,读取info中的属性时就非常不方便,处理JSON就可以使用JacksonTypeHandler处理器进行转换。

定义实体

java 复制代码
@Data
@AllArgsConstructor(staticName = "of")
@NoArgsConstructor
public class UserInfo {
    private Integer age;
    private String intro;
    private String gender;
}

使用类型处理器

将User类的info字段修改为UserInfo类型,并声明类型处理器

同时,在User类上添加一个注解,声明自动映射

为了让页面返回的结果也以对象格式返回,我们要修改UserVO中的info字段

使用swagger框架集成的页面测试

相关推荐
航叔啦21 分钟前
Mysql和sqlServer命令比较
数据库·mysql·sqlserver
BUG研究员_25 分钟前
MQ消息丢失解决方案
java·开发语言
m0_7482387827 分钟前
20.<Spring图书管理系统①(登录+添加图书)>
java·后端·spring
qq_658607583 小时前
慢sql治理
数据库·oracle
high20113 小时前
【Java 基础】-- 设计模式
java·单例模式·设计模式
LUCIAZZZ3 小时前
Java中的设计模式违反了哪些设计原则
java·开发语言·spring boot·后端·spring·设计模式
ashane13143 小时前
设计模式说明
java
powerfulzyh4 小时前
StarRocks-fe工程在Cursor中不能识别为Java项目
java·开发语言
stars4 小时前
mysql表分区
数据库·mysql
GzlAndy4 小时前
MySQL执行更新SQL流程
数据库·sql·mysql