MyBatis-Plus作为MyBatis的增强工具,提供了代码生成器、插件扩展、静态工具类、枚举类型转换器及JSON类型处理器等增强功能。代码生成器可根据数据库表自动生成实体类、Mapper、Service等代码,提高开发效率。插件如分页插件简化了分页操作。静态工具类如
LambdaQueryWrapper
支持链式调用和条件构造。枚举类型转换器使得数据库与Java枚举类型间的数据映射更加便捷。JSON类型处理器则允许直接处理JSON格式数据,增强了数据交互的灵活性。这些功能在项目中分别针对不同场景提供支持,是提升开发效率和代码质量的重要工具。
目录
代码生成
安装插件
使用步骤
静态工具
枚举类型转换器
JSON类型处理器
代码生成
由上篇可知,MybatisPlus基础的Mapper
、Service
、Po
代码相对固定,没有什么技术含量。
推荐大家使用一款MybatisPlus
的插件,它可以基于图形化界面完成MybatisPlus
的代码生成,非常简单。(就是帮助搭建一个架子,可以让咱们更专注于业务层的逻辑)
安装插件
在Idea
的plugins市场中搜索并安装MyBatisPlus
插件:
使用步骤
当你重启idea开始使用时,点击Other
点击Config Database,填写对应信息即可。
点击Code Generator,选中要生成的表,填写配置即可。(module是你的子模块,没有就不用填写)
效果如下:
Address实体类
AddressServiceImpI
代码架子生成成功
静态工具
场景描述:实现一个功能,根据一批用户的ID快速查询这些用户的基本信息以及他们的地址详情。
UserVO如下:
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如下:
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之间会相互调用,如何解决循环依赖?
具体要求如下:
- 查询用户:首先根据传入的一批用户ID集合查询用户的基本信息。如果查询结果为空,则直接返回空列表。
- 查询地址:对于查询到的每个用户,根据其ID进一步查询该用户的地址信息。
- 数据转换:将查询到的原始地址实体转换为视图对象(VO),以便于前端展示。
- 数据整理:按照用户ID对地址信息进行分类整理,确保同一用户的所有地址被归类在一起。
- 组装结果:将用户基本信息与对应的地址列表组合起来,形成最终的视图对象(VO)返回给调用方。
解决方案:MybatisPlus提供一个静态工具类:Db。
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为VOUserVO 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
转换。
定义枚举
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序列化时展示的字段
public enum UserStatus {NORMAL (1,"正常"),FROZEN (2,"冻结"),;@EnumValueprivate final int value;@JsonValueprivate final String desc;UserStatus(int value, String desc) {this.value = value;this.desc = desc;}
}
配置枚举处理器
mybatis-plus:configuration:default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler
使用swagger框架集成的页面测试
JSON类型处理器
数据库的user表中有一个info
字段,是JSON类型,而目前User
实体类中却是String
类型,读取info中的属性时就非常不方便,处理JSON就可以使用JacksonTypeHandler
处理器进行转换。
定义实体
@Data
@AllArgsConstructor(staticName = "of")
@NoArgsConstructor
public class UserInfo {private Integer age;private String intro;private String gender;
}
使用类型处理器
将User类的info字段修改为UserInfo类型,并声明类型处理器
同时,在User类上添加一个注解,声明自动映射
为了让页面返回的结果也以对象格式返回,我们要修改UserVO中的info字段
使用swagger框架集成的页面测试