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框架集成的页面测试

相关推荐
爱笑的源码基地9 分钟前
高并发 Redis 缓存门诊HIS系统源码,含财务统计药房进销存
java·程序·门诊系统·诊所系统·云诊所源码
憧憬成为web高手9 分钟前
皮卡丘靶场速通--sql 2
数据库·sql·mybatis
段一凡-华北理工大学22 分钟前
向量数据库实战:选型、调优与落地~系列文章12:文本分块策略实战:chunk_size 怎么选?重叠多少?
开发语言·数据库·后端·oracle·rust·工业智能体·高炉智能化
oradh2 小时前
Oracle XTTS实现跨版本迁移和升级(Oracle 11g单库升级至19C RAC集群)
数据库·oracle·11g升级19c·xtts跨版本迁移和升级
莫逸风3 小时前
【AgentScope 2.0】 0. 学习指南
java·llm·agent·agentscope
z123456789863 小时前
2026最新两款AI编程工具深度对比实测
java·数据库·ai编程
程序猿DD3 小时前
一个 API Key,统一调用大模型、生图和联网搜索
数据库·网关
yaoxin5211234 小时前
470. Java 反射 - Member 接口与 AccessFlag
java·开发语言·python
做个文艺程序员4 小时前
Linux第24篇:Java应用监控体系搭建:Prometheus+Grafana可视化运维
java·grafana·prometheus
TlSfoward4 小时前
抓包代理链路下的 TLS 指纹变化分析 TLSFOWARD抓包工具
数据库·爬虫·网络协议·搜索引擎·php