在上一篇文章讲述了如何使用Mybatis-plus自动生成代码,生成的代码具有单表操作数据库的能力,节约了开发时间。然后讲述了如何在Spring Boot中整合Mybatis-Plus。这篇文章讲述如何使用Mybatis-Plus的增强功能:自动填充功能和查询分页功能。

Mybatis-Plus自动填充功能

在Matrix-web项目中,数据库的所有表都有四个公共字段,即create_by、create_time、update_by、update_time ,即存储了表数据的创建人、创建时间、更新时间、更新人。在对表插入一条数据的时候,需要自动填充四个字段,对表数据更新操作,需要更新后2个字段。但是如果在每个插入和更新业务逻辑里面, 手动的填充这四个字段,增加了工作量。幸好mybatis-plus有一个自动更新的插件。

实现自动填充功能很简单,只需要实现MetaObjectHandler接口和实现填充逻辑,并把它注入到spring ioc容器中即可。其中下面的代码UserUtils.getCurrentUserWithDefault();即获取当前请求的用户,在权限那一篇文章有讲到过,在这里不再重复;然后加上注解@Component注入到Spring ioc容器里面去。

@Component
@Slf4j
public class MyMetaObjectHandler implements MetaObjectHandler {@Overridepublic void insertFill(MetaObject metaObject) {log.info("start insert fill ....");Object createBy = getFieldValByName("createBy", metaObject);Object updateBy = getFieldValByName("updateBy", metaObject);Object createTime = getFieldValByName("createTime", metaObject);Object updateTime = getFieldValByName("updateTime", metaObject);if (createBy == null) {this.setFieldValByName("createBy", UserUtils.getCurrentUserWithDefault(), metaObject);//版本号3.0.6以及之前的版本}if (updateBy == null) {this.setFieldValByName("updateBy", UserUtils.getCurrentUserWithDefault(), metaObject);}if (createTime == null) {this.setFieldValByName("createTime", new Date(), metaObject);}if (updateTime == null) {this.setFieldValByName("updateTime", new Date(), metaObject);}}@Overridepublic void updateFill(MetaObject metaObject) {log.info("start update fill ....");Object updateBy = getFieldValByName("updateBy", metaObject);Object updateTime = getFieldValByName("updateTime", metaObject);if (updateBy == null) {this.setFieldValByName("updateBy", UserUtils.getCurrentUserWithDefault(), metaObject);}if (updateTime == null) {this.setFieldValByName("updateTime", new Date(), metaObject);}}
}
  • 字段必须声明TableField注解,属性fill选择对应策略,该申明告知 Mybatis-Plus 需要预留注入 SQL 字段

  • 填充处理器MyMetaObjectHandler 在 Spring Boot 中需要声明@Component 注入

  • 必须使用父类的setFieldValByName()或者setInsertFieldValByName/setUpdateFieldValByName方法,否则不会根据注解FieldFill.xxx来区分。

public enum FieldFill {/*** 默认不处理*/DEFAULT,/*** 插入填充字段*/INSERT,/*** 更新填充字段*/UPDATE,/*** 插入和更新填充字段*/INSERT_UPDATE
}

然后再表中映射的实体类,加上该上面的相应的注解即可,比如在Matrix-Web中所有数据库映射的实体类都继承BaseEntity。

@Data
public class BaseEntity {@JsonSerialize(using= ToStringSerializer.class)@TableId(value = "id", type = IdType.ID_WORKER)protected Long id;/*** 创建时间*/@TableField(value = "create_time", fill = FieldFill.INSERT)protected Date createTime;/*** 创建人id*/@TableField(value = "create_by", fill = FieldFill.INSERT)protected String createBy;/*** 更新时间*/@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)protected Date updateTime;/*** 更新人*/@TableField(value = "update_by", fill = FieldFill.INSERT_UPDATE)protected String updateBy;}

比如SysUser实体类继承上面的BaseEntity。

@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class SysUser extends BaseEntity {
...
}

当调用SysUserMapper插入SysUser数据的时候,就会自动在数据库中插入create_by、create_time、update_by、update_time这四个数据。

分页插件

在Web开发中,经常用到分页插件。Mybatis-Plus提供了这样的能力。需要在spring ioc容器注入PaginationInterceptor,代码如下:

@Configuration
public class MybatisPlusConfig {/*** 分页插件*/@Beanpublic PaginationInterceptor paginationInterceptor() {return new PaginationInterceptor();}
}

现在以一个具体的案例来讲述如何分页。比如查询SysUser的分页。在Controller层:

@GetMapping("/pagelist")
public RespDTO searchUsers(@RequestParam int page, @RequestParam int pageSize, @RequestParam(required = false) String userId, @RequestParam(required = false) String realname) {PageUtils.check(page, pageSize);PageResultsDTO sysUsers = sysUserService.searchUsers(page, pageSize, userId, realname);return RespDTO.onSuc(sysUsers);}

在上面的代码中需要必传2个参数,page和pageSize,即页数和每页的数量。PageUtils.check(page, pageSize)是检查page和pageSize是否合理。RespDTO是返回给前端的DTO类。具体代码如下:

public class RespDTO<T> implements Serializable {public int code = 0;public String message = "";public T data;public String requestId;
}

PageResultsDTO是存放分页的数据和分页的元数据,代码如下:

public class PageResultsDTO<T> {public List<T> list = new ArrayList<>();public int page;public int pageSize;public long totalCount;public int offset;public int totalPage;}

Sevice层代码,需要将sysUserMapper查询的数据包装到PageResultsDTO中代码如下:

  public PageResultsDTO searchUsers(int page, int pageSize, String userId, String realname) {Page<SysUser> sysLogPage = new Page<>(page, pageSize);IPage<SysUser> sysUserIPage = sysUserMapper.searchUsers(sysLogPage, userId, realname);PageResultsDTO result = new PageResultsDTO(page, pageSize);result.setTotalCount(sysUserIPage.getTotal());result.setTotalPage((int) sysUserIPage.getTotal(), pageSize);List<SysUser> records = sysUserIPage.getRecords();result.setList(transformSysUserDTO(records));return result;}

SysUserMapper的searchUsers方法会查询数据库,获取数据:

@Mapper
public interface SysUserMapper extends BaseMapper<SysUser> {IPage<SysUser> searchUsers(Page page, @Param("userId") String userId,@Param("realname") String realname);
}

SysUserMapper的查询数据库的sql语句,需要自己写,在SysUserMapper.xml中,

    <select id="searchUsers" resultMap="BaseResultMap">SELECT a.id as id ,a.create_time as create_time, a.create_by as create_by,a.update_time as update_time,a.update_by as update_by,a.user_id as user_id,a.password as password,a.realname as realname,a.type as type,a.mobile as mobile,a.email as email,a.remarks as remarks ,a.status as status,a.avatar as avatar,a.sex as sex,c.name as role_name,c.role_id as role_role_id ,e.org_id as org_id,e.simple_name as simple_name,g.code as code,g.url as urlfrom sys_user aLEFT JOIN  sys_user_role b on a.user_id=b.user_idLEFT JOIN  sys_role c on b.role_id=c.role_idLEFT JOIN sys_user_org d on a.user_id=d.user_idleft JOIN sys_org e on d.org_id =e.org_idleft join sys_role_menu f on f.role_id=c.role_idleft join sys_menu g on g.code=f.menu_code<where><if test="userId != null and userId!='' ">a.user_id = #{userId}</if><if test="realname != null and realname!='' ">AND a.realname = #{realname}</if></where></select>

这是完整的使用Mybatis-Plus插件分页的案例。前端代码就不在这里讲解了,在前端界面展示的分页效果如下:

总结

这篇文章讲述了如何使用Mybatis-Plus的增强功能,自动填充和分页。下篇文章将讲述如何使用Durid连接池和Sharding-JDBC实现数据库读写分离。

参加资料:

https://mp.baomidou.com/guide/#%E7%89%B9%E6%80%A7

源码下载

https://github.com/forezp/matrix-web

往期文章:

跟我学Springboot开发后端管理系统1:概述

跟我学Springboot开发后端管理系统2:Mybatis-Plus实战

跟我学Springboot开发后端管理系统3:Mybatis-Plus实战2相关推荐

  1. 跟我学Springboot开发后端管理系统2:Mybatis-Plus实战

    在Matrix-Web项目中使用Mybatis-Plus作为操作数据库的ORM框架.在市面上常用的ORM框架有hibernetes.mybatis.JPA等,那么为什么选择Mybatis-Plus呢? ...

  2. mybatis plus springboot test_跟我学Springboot开发后端管理系统3:Mybatis-Plus实战2

    文章来源:https://mp.weixin.qq.com/s/YL0FDjn8BczNfIJJ9DgMRA 原文作者:forezp 来源平台:微信公众号 在上一篇文章讲述了如何使用Mybatis-p ...

  3. 跟我学Springboot开发后端管理系统9:AOP+logback+MDC日志输出

    MDC介绍 在比较复杂的应用中,一个请求需要走很多个方法的处理,怎么样才能快速查找一个请求的全部日志呢.在分布式系统中,我们可以用链路追踪,比如zipkin.skywalking去快速查找日志,从而定 ...

  4. 跟我学Springboot开发后端管理系统8:Matrxi-Web权限设计实现

    上篇文章讲述了Matrix-web整体实现的权限控制的思路.现在来回顾一下: 首先,用户需要登录,填用户名.密码,后端接收到登录请求,进行用户.密码的校验,校验成功后则根据用户名生成Token,并返回 ...

  5. 跟我学Springboot开发后端管理系统7:Matrxi-Web权限设计

    Matrxi-Web权限设计 对于一个后端系统来说,权限是基础设施,是安全保障.没有权限,系统可能随时面临各种风险,所以权限设计对后端系统来说至关重要.在Javaweb开发中,有很多权限开发的框架,比 ...

  6. 跟我学Springboot开发后端管理系统6:缓存框架Caffeine

    Caffeine是一个基于Java8的高性能缓存框架,号称趋于完美.Caffeine受启发于Guava Cache的API,使用API和Guava是一致的.它借鉴了Guava Cache和Concur ...

  7. 跟我学Springboot开发后端管理系统5:数据库读写分离

    在Matrix-web后台管理系统中,使用到了数据库的读写分离技术.采用的开源的Sharding-JDBC作为数据库读写分离的框架.Matrix-Web后台数据库这一块采用的技术栈如下: 使用Myba ...

  8. 跟我学Springboot开发后端管理系统4:数据库连接池Druid和HikariCP

    上一篇文章主要讲解了如何再Matrix-Web中使用Mybatis-Plus,Mybatis-Plus作为Orm框架,连接数据库需要连接数据库的依赖.WEB 系统高并发环境下,频繁的进行数据库连接操作 ...

  9. 跟我学Springboot开发后端管理系统8:AOP+logback+MDC日志输出

    MDC介绍 在比较复杂的应用中,一个请求需要走很多个方法的处理,怎么样才能快速查找一个请求的全部日志呢.在分布式系统中,我们可以用链路追踪,比如zipkin.skywalking去快速查找日志,从而定 ...

最新文章

  1. android edittext 默认不获取焦点
  2. matplotlib 入门之Image tutorial
  3. linux里的dd权限不够怎么办,Linux dd 遇到 容量不足 的 resize 解法
  4. 这篇文章让我步入了无线时代,感激原创。
  5. Python调用模块发送邮件(粗糙版)
  6. P4755-Beautiful Pair【笛卡尔树,线段树】
  7. 录制caf 转 mp3
  8. 【转】[教程] CSS入门3:如何插入CSS样式
  9. centos 安装oracle java,CentOS 4.4下安装Oracle 10
  10. JVM 性能调优监控工具
  11. iPhone 12快来了!苹果或本周公布发布会时间
  12. python词云图背景_python词云图之WordCloud
  13. Incorrect string value: ‘\xE4\xBB\x8E\xE5\x85\xA5...‘ for column ‘detail‘ at row 1
  14. Work Stealing
  15. NSDate计算时间差
  16. Markdown还能这么玩?这款开源神器绝了!
  17. 亿信华辰:怎样去断定一份数据的质量高低?数据质量如何评估?
  18. 基于MATLAB的数字图像处理基本操作
  19. 双剑合璧——IT与OT的深度融合之趋
  20. 基于Android的相关毕业设计和论文

热门文章

  1. 循环for语句 if语句
  2. Flink学习笔记:Operators之CoGroup及Join操作
  3. 日期类的时间从为什么是从1970年1月1日(格林威治时间)
  4. document.readystate
  5. .PHONY makefile中的伪目标
  6. UVA 10269 Adventure of Super Mario
  7. 【青少年编程竞赛交流】10月份微信图文索引
  8. 学习资源:在线学习 Python(一)
  9. 鼠标按键获取感兴趣区域 2
  10. 干货满满的 Python 实战项目,点赞收藏