当前位置: 首页 > news >正文

MybatisPlus - 扩展功能

文章目录

    • 目标:
      • 1.代码生成
        • 2.静态工具
        • 3.逻辑删除
        • 4.枚举处理器
        • 5.JSON处理器
      • 插件功能

在这里插入图片描述

目标:

  • 代码生成
  • 静态工具
  • 逻辑删除
  • 每局处理器
  • JSON处理器

1.代码生成

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

这个自己试试叭!

2.静态工具

在这里插入图片描述
跟IService的很像,但是IService中的方法都是非静态的,所以我们要自定义接口并且继承它,继承它的过程中还要指定泛型,泛型就是实体类的类型,为什么要执行实体类的类型?因为要通过反射获取字节码得到表信息才能增删改查。而Db都是静态的。类上是没有泛型的或者说静态的方法是没有办法读取到泛型的,因此Db上是没有泛型的,那么如何去做增删改查呢?所以你发现它的方法都需要我们传递一个额外的参数-字节码。
在这里插入图片描述
查地址的时候要注入user,查user的时候要注入地址,出现了循环依赖,那么我们就可以通过这个静态工具来解决。

AddressVO

@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;
}

UserVO

@Data
@ApiModel(description = "用户VO实体")
public class UserVO {@ApiModelProperty("用户id")private Long id;@ApiModelProperty("用户名")private String username;@ApiModelProperty("详细信息")private String info;@ApiModelProperty("使用状态(1正常 2冻结)")private Integer status;@ApiModelProperty("账户余额")private Integer balance;private List<AddressVO> addresses;
}

出现循环依赖可以使用静态工具

public UserVO queryUserAndAddressById(Long id) {//1.查询用户User user = this.getById(id);if(user==null || user.getStatus()!=1){throw new RuntimeException("用户状态异常");}//2.查询地址List<Address> addresses = Db.lambdaQuery(Address.class).eq(Address::getUserId, id).list();//3.封装返回值UserVO userVO = BeanUtil.copyProperties(user, UserVO.class);if(addresses!=null && addresses.size()>0){userVO.setAddresses(BeanUtil.copyToList(addresses, AddressVO.class));}return userVO;}

第二题

 @ApiOperation("根据id批量查询用户接口")@PostMapping("/users")public List<UserVO> queryUser(@RequestParam("ids") List<Long> ids){return userService.queryUserAndAddressByIds(ids);}
 public List<UserVO> queryUserAndAddressByIds(List<Long> ids) {//1.查询用户List<User> users = listByIds(ids);if(users==null || users.size()!=ids.size()){throw new RuntimeException("用户状态异常");}//2.查询地址//2.1 获取用户id集合List<Long> userIds = users.stream().map(User::getId).collect(Collectors.toList());//2.2 查询地址List<Address> addresses = Db.lambdaQuery(Address.class).in(Address::getUserId, userIds).list();//2.3 转换Address的PO为VOList<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.封装返回值List<UserVO>list = new ArrayList<>(users.size());for (User user : users) {//3.1 转换User的PO为VOUserVO userVO = BeanUtil.copyProperties(user, UserVO.class);list.add(userVO);userVO.setAddresses(addressMap.get(user.getId()));}return list;}
3.逻辑删除

有一些数据是非常重要的,不能直接删除

在这里插入图片描述
在这里插入图片描述
我配完之后写了一个测试类测试一下:

@SpringBootTest
class IAddressServiceTest {@Autowiredprivate IAddressService addressService;@Testvoid testLogicDelete(){addressService.removeById(60L);Address address = addressService.getById(60L);System.out.println(address);}}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.枚举处理器

在这里插入图片描述
这里我们会涉及到枚举类型跟int类型之间的转换问题,其实也不仅仅是这一个;类型,我们java中所有的数据类型都要跟数据库的类型做转换,可能我们平时都没有主动转换过,但是我们没有做过并不代表没有,我们所认为的岁月静好,只不过是有人在替我们负重前行,底层都是由mybatis帮我们完成,mybatis如何实现类型转换呢?
在这里插入图片描述
在这里插入图片描述
我们这里使用MybatisEnum TypeHandler,分两步使用,我们得告诉mp那个属性是对应数据库的字段,用注解@EnumValue
在这里插入图片描述
第二步:让它生效
在这里插入图片描述
记得VO也要改,但是返回就会以枚举项返回,我们的数据往前端返回是由SpringMVC处理的,SpringMVC处理JSON用的是Jackson,它提供了一个注解来表明返回枚举中那个值进行返回@JsonValue
在这里插入图片描述
在这里插入图片描述

5.JSON处理器

在这里插入图片描述
在这里插入图片描述
但是mybatis没有能力帮我们做userInfo跟JSON数据类型的转换,所以我们只能自己来
在这里插入图片描述
我们使用JacksonTypeHandler实现类
在这里插入图片描述
没有全局配置,只能一个个配.现在这里面出现了对象嵌套,User中又出现了info
往往就需要去定义resultMap,但是我们又不想定义

在这里插入图片描述
准备实体:
在这里插入图片描述

插件功能

在这里插入图片描述
最常见,我们一般可以用pageHelper,但是mp也提供了
这里分为两个小节

  • 分页插件
  • 通用分页实体

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
配置

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class MyBatisConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();// 这里可以添加多个插件PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);paginationInnerInterceptor.setMaxLimit(1000L);interceptor.addInnerInterceptor(paginationInnerInterceptor);return interceptor;}
}

测试类:

 @Testvoid testPageQuery(){int pageNo = 1;int pageSize = 2;//1.准备分页条件//1.1分页条件Page<User>page = new Page<>(pageNo, pageSize);//1.2排序条件page.addOrder(OrderItem.desc("id"));//2.执行分页查询Page<User> result = userService.page(page);//3.输出结果result.getRecords().forEach(System.out::println);System.out.println("总记录数:" + result.getTotal());System.out.println("总页数:" + result.getPages());System.out.println("当前页:" + result.getCurrent());System.out.println("是否有前一页:" + result.hasPrevious());System.out.println("是否有下一页:" + result.hasNext());}

在这里插入图片描述

在这里插入图片描述
返回值:
在这里插入图片描述
通用分页实体
封装一个实体:

import lombok.Data;@Data
public class PageQuery {private Integer pageNo;private Integer pageSize;private String sortBy;private Boolean isAsc;
}
@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel(description = "用户查询条件实体")
public class UserQuery extends PageQuery {@ApiModelProperty("用户名关键字")private String name;@ApiModelProperty("用户状态:1-正常,2-冻结")private Integer status;@ApiModelProperty("余额最小值")private Integer minBalance;@ApiModelProperty("余额最大值")private Integer maxBalance;
}

定义一个统一分页结果,我们说不定以后在微服务中也会使用到所以可以定义在dto包

@Data
public class PageDTO<T> {private Long total;private Long pages;private List<T> list;
}

接口声明:

    @ApiOperation("根据复杂条件分页查询用户接口")@GetMapping("/page")public PageDTO<UserVO> queryUsersPage(UserQuery query){return userService.queryUsersPage(query);}
 public PageDTO<UserVO> queryUsersPage(UserQuery query) {//1.构建查询条件String name = query.getName();Integer status = query.getStatus();Page<User> page = Page.of(query.getPageNo(), query.getPageSize());if(StrUtil.isNotBlank(query.getSortBy())){page.addOrder(new OrderItem(query.getSortBy(), query.getIsAsc()));}else{//默认排序page.addOrder(new OrderItem("update_time"  , false));}//2.分页查询Page<User> p = lambdaQuery().like(name != null, User::getUsername, name).eq(status != null, User::getStatus, status).page(page);//3.转换PO为VOPageDTO<UserVO> dto = new PageDTO<>();dto.setTotal(p.getTotal());dto.setPages(p.getPages());List<User> records = p.getRecords();if(CollUtil.isEmpty(records)){dto.setList(new ArrayList<>());return dto;}//3.1 转换User的PO为VOdto.setList(BeanUtil.copyToList(records, UserVO.class));//3.2 封装地址信息//4.返回return dto;}

在这里插入图片描述

通用分页实体与MP转换
在这里插入图片描述
很多代码跟业务关系不大,比较通用

在这里插入图片描述

@Data
public class PageQuery {private Integer pageNo = 1;private Integer pageSize = 5;private String sortBy;private Boolean isAsc = true;public <T> Page<T> toMpPage(OrderItem ...items){Page<T> page = Page.of(pageNo, pageSize);if(StrUtil.isNotBlank(sortBy)){page.addOrder(new OrderItem(sortBy, isAsc));}else if(items!= null && items.length > 0){//默认排序page.addOrder(items);}return page;}public <T> Page<T> toMpPage(String sortBy, Boolean isAsc){return toMpPage(new OrderItem(sortBy, isAsc));}public <T> Page<T> toMpPageDefaultByCreatTime(){return toMpPage(new OrderItem("create_time",false));}public <T> Page<T> toMpPageDefaultByUpdateTime(){return toMpPage(new OrderItem("update_time",false));}
}
import java.util.ArrayList;
import java.util.List;@Data
public class PageDTO<T> {private Long total;private Long pages;private List<T> list;public static <PO,VO> PageDTO<VO> of(Page<PO> p,Class<VO> voClass){PageDTO<VO> dto = new PageDTO<>();dto.setTotal(p.getTotal());dto.setPages(p.getPages());List<PO> records = p.getRecords();if(CollUtil.isEmpty(records)){dto.setList(new ArrayList<>());return dto;}//3.1 转换User的PO为VOdto.setList(BeanUtil.copyToList(records, voClass));//3.2 封装地址信息//4.返回return dto;}
}

最终:

  public PageDTO<UserVO> queryUsersPage(UserQuery query) {//1.构建查询条件String name = query.getName();Integer status = query.getStatus();Page<User> page = query.toMpPage();//2.分页查询Page<User> p = lambdaQuery().like(name != null, User::getUsername, name).eq(status != null, User::getStatus, status).page(page);//3.转换PO为VOreturn PageDTO.of(p,  UserVO.class);}

但是要记住Beanutil的使用要求User,UserVo的属性名要相同,如果不同需要自己完成转换,那能不能封装一个方法别的方法你帮我写好但是从PO到VO的转换我自己来写

public class PageDTO<T> {private Long total;private Long pages;private List<T> list;public static <PO,VO> PageDTO<VO> of(Page<PO> p, Function<PO,VO> converter){PageDTO<VO> dto = new PageDTO<>();dto.setTotal(p.getTotal());dto.setPages(p.getPages());List<PO> records = p.getRecords();if(CollUtil.isEmpty(records)){dto.setList(new ArrayList<>());return dto;}//3.1 转换User的PO为VOdto.setList(records.stream().map(converter).collect(Collectors.toList()));//3.2 封装地址信息//4.返回return dto;}
}
public PageDTO<UserVO> queryUsersPage(UserQuery query) {//1.构建查询条件String name = query.getName();Integer status = query.getStatus();Page<User> page = query.toMpPage();//2.分页查询Page<User> p = lambdaQuery().like(name != null, User::getUsername, name).eq(status != null, User::getStatus, status).page(page);//3.转换PO为VOreturn PageDTO.of(p, user->{//1.拷贝基础属性UserVO vo = BeanUtil.copyProperties(user, UserVO.class);//2.处理特殊逻辑vo.setUsername(vo.getUsername().substring(0,vo.getUsername().length()-2)+"**");return vo;});}

在这里插入图片描述

完结啦~~


http://www.mrgr.cn/news/64358.html

相关文章:

  • 使用onnxruntime-web 运行yolov8-nano推理
  • 贪心算法习题其三【力扣】【算法学习day.20】
  • 63 mysql 的 行锁
  • Ubantu/Linux 采用Repo或Git命令报错!!
  • Java 用户随机选择导入ZIP文件,解压内部word模板并入库,Windows/可视化Linux系统某麒麟国防系统...均可适配
  • 数据挖掘(四)
  • 文献阅读记录6-Toward computer-made artificial antibiotics
  • 初始JavaEE篇——多线程(8):JUC的组件
  • EDM平台升级 送达率与效果并进
  • tftp协议笔记
  • 【C++刷题】力扣-#643-子数组最大平均数I
  • 堆的实现--数据结构
  • 重装linux系统
  • 网页自动化测试和爬虫:Selenium库入门与进阶
  • C语言中的希尔排序
  • 大厂面试真题-如果使用guava limiter实现实例级别的缓存
  • JSP ft06 问题几个求解思路整理
  • 我国在AI领域的发展趋势
  • 【springcloud】服务之间调用失败的重试机制
  • 微服务架构面试内容整理-微服务架构的定义及优势
  • C++ --- 多线程的使用
  • 《程序内存需求估算:职场中的“暗礁”与“灯塔”》
  • 网络通信与并发编程(九)asyncio
  • 【ReactPress】一款基于React的开源博客CMS内容管理平台—ReactPress
  • Python Turtle模块详解与使用教程
  • ITK-膨胀