本文主要介绍 MyBatis Plus 的使用,顺便讲一下分页。
MyBatis Plus 是基于MyBatis 做了层封装,只需要继承它的 BaseDao, 我们就不需要写很多简单的 CURD,而且mapper实现也不用写,可以说瞬间减轻了一部分工作量。而且它也自带分页插件,不需要再使用 PageHelper 了。
2. application.yml
注意修改第二行的 xml 文件位置和第4行的实体包位置
3. 代码结构
注意关注 entity、mapper类 和 mapper.xml 位置,注意和上面的配置文件对应
4. MyBatis Plus 配置类
这里以日志类作为一个Demo演示,包含增删改查
1.实体
2.Mapper 类
我们查看 BaseMapper,发现里面已经常用的 insert/updateById/selectById/delete/deleteById 等方法,
需要自定义的,按照传统方法添加就行了
3.Mapper xml
关于增删改查的基本接口不需要写了
4.Service实现
第4个方法是分页查询,为下面的做铺垫
相信用过 MyBatis 的朋友,开始使用 MyBatis Plus 上手很快的。
承接上面的代码,我们实现日志分页显示
1.添加配置
上面 MybatisPlusConfig 中已经添加了分页拦截器
2. Controller 层
主要关注第13-14行
3.Page 类
不要导错包
分页对象主要包含以下几个重要字段
records:数据列表
total:总记录数
pages:总页数
size:页大小,一页显示多少条
current:当前页码(从第1页开始)
以本站首页分页样式为例
1.引入FreeMaerker
2.application.yml
3. html 代码部分如下
效果如下
MyBatis Plus 是基于MyBatis 做了层封装,只需要继承它的 BaseDao, 我们就不需要写很多简单的 CURD,而且mapper实现也不用写,可以说瞬间减轻了一部分工作量。而且它也自带分页插件,不需要再使用 PageHelper 了。
一、SpringBoot 2.0 整合 MyBatis Plus
- pom.xml
- <!-- mybatis-plus begin -->
- <dependency>
- <groupId>com.baomidou</groupId>
- <artifactId>mybatisplus-spring-boot-starter</artifactId>
- <version>1.0.5</version>
- </dependency>
- <dependency>
- <groupId>com.baomidou</groupId>
- <artifactId>mybatis-plus</artifactId>
- <version>2.1.8</version>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-jdbc</artifactId>
- </dependency>
- <!--mybatis-plus end-->
2. application.yml
- mybatis-plus:
- mapper-locations: classpath*:/mapper/**Mapper.xml
- #实体扫描,多个package用逗号或者分号分隔
- typeAliasesPackage: com.liuyanzhao.sens.entity
- global-config:
- #主键类型 0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";
- id-type: 0
- #字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断"
- field-strategy: 2
- #驼峰下划线转换
- db-column-underline: true
- #刷新mapper 调试神器
- refresh-mapper: true
- #逻辑删除配置(下面3个配置)
- logic-delete-value: 0
- logic-not-delete-value: 1
- configuration:
- map-underscore-to-camel-case: true
- cache-enabled: false
注意修改第二行的 xml 文件位置和第4行的实体包位置
3. 代码结构
注意关注 entity、mapper类 和 mapper.xml 位置,注意和上面的配置文件对应
4. MyBatis Plus 配置类
- package com.liuyanzhao.sens.config;
- import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
- import com.baomidou.mybatisplus.plugins.PerformanceInterceptor;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- /**
- * @author 言曌
- * @date 2018/12/22 下午1:49
- */
- @Configuration
- public class MybatisPlusConfig {
- /***
- * plus 的性能优化
- * @return
- */
- @Bean
- public PerformanceInterceptor performanceInterceptor() {
- PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
- /*<!-- SQL 执行性能分析,开发环境使用,线上不推荐。 maxTime 指的是 sql 最大执行时长 -->*/
- performanceInterceptor.setMaxTime(1000);
- /*<!--SQL是否格式化 默认false-->*/
- performanceInterceptor.setFormat(true);
- return performanceInterceptor;
- }
- /**
- * mybatis-plus分页插件
- */
- @Bean
- public PaginationInterceptor paginationInterceptor() {
- return new PaginationInterceptor();
- }
- }
二、开始使用
这里以日志类作为一个Demo演示,包含增删改查
1.实体
- package com.liuyanzhao.sens.entity;
- import com.baomidou.mybatisplus.annotations.TableId;
- import com.baomidou.mybatisplus.annotations.TableName;
- import com.baomidou.mybatisplus.enums.IdType;
- import lombok.Data;
- import java.io.Serializable;
- import java.util.Date;
- /**
- * <pre>
- * 操作日志
- * </pre>
- *
- * @author : saysky
- * @date : 2018/1/19
- */
- @Data
- @TableName("sens_log")
- public class Log implements Serializable {
- private static final long serialVersionUID = -2571815432301283171L;
- /**
- * id
- */
- @TableId(type = IdType.AUTO)
- private Long logId;
- /**
- * 标题
- */
- private String logTitle;
- /**
- * 内容
- */
- private String logContent;
- /**
- * 产生日志的ip
- */
- private String logIp;
- /**
- * 产生的时间
- */
- private Date logCreated;
- public Log() {
- }
- public Log(String logTitle, String logContent, String logIp, Date logCreated) {
- this.logTitle = logTitle;
- this.logContent = logContent;
- this.logIp = logIp;
- this.logCreated = logCreated;
- }
- }
2.Mapper 类
- package com.liuyanzhao.sens.mapper;
- import com.baomidou.mybatisplus.mapper.BaseMapper;
- import com.baomidou.mybatisplus.plugins.pagination.Pagination;
- import com.liuyanzhao.sens.entity.Log;
- import org.apache.ibatis.annotations.Mapper;
- import java.util.List;
- /**
- * 日志Mapper
- * @author liuyanzhao
- */
- @Mapper
- public interface LogMapper extends BaseMapper<Log> {
- /**
- * 查询所有
- * @param pagination 分页信息
- * @return List
- */
- List<Log> findAll(Pagination pagination);
- /**
- * 查询最新的五条数据
- *
- * @return List
- */
- List<Log> findTopFive();
- /**
- * 删除所有的记录
- * @return 影响行数
- */
- Integer deleteAll();
- }
我们查看 BaseMapper,发现里面已经常用的 insert/updateById/selectById/delete/deleteById 等方法,
需要自定义的,按照传统方法添加就行了
3.Mapper xml
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
- <mapper namespace="com.liuyanzhao.sens.mapper.LogMapper">
- <resultMap id="BaseResultMap" type="com.liuyanzhao.sens.entity.Log">
- <id column="log_id" jdbcType="INTEGER" property="logId"/>
- <result column="log_title" jdbcType="VARCHAR" property="logTitle"/>
- <result column="log_content" jdbcType="VARCHAR" property="logContent"/>
- <result column="log_ip" jdbcType="VARCHAR" property="logIp"/>
- <result column="log_created" jdbcType="TIMESTAMP" property="logCreated"/>
- </resultMap>
- <sql id="all_columns">
- log_id, log_title, log_content, log_ip, log_created
- </sql>
- <sql id="tb">`sens_log`</sql>
- <sql id="all_values">
- #{logId}, #{logTitle}, #{logContent}, #{logIp}, #{logCreated}
- </sql>
- <select id="findAll" resultMap="BaseResultMap">
- SELECT
- <include refid="all_columns"/>
- FROM
- <include refid="tb"/>
- </select>
- <select id="findTopFive" resultMap="BaseResultMap">
- SELECT
- <include refid="all_columns"/>
- FROM
- <include refid="tb"/>
- ORDER BY log_id DESC LIMIT 5
- </select>
- <delete id="deleteAll">
- DELETE FROM <include refid="tb"/>
- </delete>
- </mapper>
关于增删改查的基本接口不需要写了
4.Service实现
- package com.liuyanzhao.sens.service.impl;
- import com.baomidou.mybatisplus.plugins.Page;
- import com.liuyanzhao.sens.entity.Log;
- import com.liuyanzhao.sens.mapper.LogMapper;
- import com.liuyanzhao.sens.service.LogService;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Service;
- import java.util.List;
- /**
- * <pre>
- * 日志业务逻辑实现类
- * </pre>
- *
- * @author : saysky
- * @date : 2018/1/19
- */
- @Service
- public class LogServiceImpl implements LogService {
- @Autowired(required = false)
- private LogMapper logMapper;
- /**
- * 保存日志
- *
- * @param log log
- * @return log
- */
- @Override
- public Log saveByLog(Log log) {
- logMapper.insert(log);
- return log;
- }
- /**
- * 根据编号移除
- *
- * @param logId logId
- */
- @Override
- public void removeByLogId(Long logId) {
- logMapper.deleteById(logId);
- }
- /**
- * 移除所有日志
- */
- @Override
- public void removeAllLog() {
- logMapper.deleteAll();
- }
- /**
- * 查询所有日志并分页
- *
- * @param page 分页信息
- * @return Page
- */
- @Override
- public Page<Log> findAllLog(Page<Log> page) {
- return page.setRecords(logMapper.findAll(page));
- }
- /**
- * 查询最新的五条日志
- *
- * @return List
- */
- @Override
- public List<Log> findLogLatest() {
- return logMapper.findTopFive();
- }
- /**
- * 根据编号查询
- *
- * @param logId logId
- * @return Optional
- */
- @Override
- public Log findLogByLogId(Long logId) {
- return logMapper.selectById(logId);
- }
- }
第4个方法是分页查询,为下面的做铺垫
相信用过 MyBatis 的朋友,开始使用 MyBatis Plus 上手很快的。
三、分页
承接上面的代码,我们实现日志分页显示
1.添加配置
上面 MybatisPlusConfig 中已经添加了分页拦截器
2. Controller 层
- /**
- * 日志分页
- *
- * @param model model
- * @param page 当前页码
- * @return 模板路径/themes/{theme}/index
- */
- @GetMapping(value = "logs")
- public String index(Model model,
- @RequestParam(name = "page",required = false, defaultValue = "1") Integer page,
- @RequestParam(name = "size",required = false, defaultValue = "10") Integer size) {
- //所有日志数据,分页
- Page pageable = new Page(page , size);
- Page<Log> logs = postService.findPostByStatus(pageable);
- model.addAttribute("logs", logs);
- return this.render("index");
- }
主要关注第13-14行
3.Page 类
不要导错包
分页对象主要包含以下几个重要字段
records:数据列表
total:总记录数
pages:总页数
size:页大小,一页显示多少条
current:当前页码(从第1页开始)
四、引入 FreeMarker 渲染页面
以本站首页分页样式为例
1.引入FreeMaerker
- <!-- freemarker依赖 -->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-freemarker</artifactId>
- </dependency>
2.application.yml
- spring:
- freemarker:
- allow-request-override: false
- cache: false
- check-template-location: true
- charset: utf-8
- content-type: text/html
- expose-request-attributes: false
- expose-session-attributes: false
- expose-spring-macro-helpers: true
- suffix: .ftl
- settings:
- auto_import: /spring.ftl as spring
- template_update_delay: 0
3. html 代码部分如下
- <nav class="navigation pagination" role="navigation">
- <h2 class="screen-reader-text">文章导航</h2>
- <div class="nav-links">
- <#assign totalPages = posts.pages>
- <#assign totalElements = posts.total>
- <#assign number = posts.current>
- <#assign first = (posts.current == 1)>
- <#assign last = (posts.current == posts.pages)>
- <#assign hasPrevious = (posts.current > 1)>
- <#assign hasNext = (posts.current < posts.pages)>
- ${totalPages} ${totalElements} ${number}
- <#--上一页-->
- <#if hasPrevious>
- <a class="prev page-numbers" href="${prefix}/page/${number-1}">
- <i class="fa fa-angle-left"></i>
- </a>
- </#if>
- <#--总页数小于等于7全部显示-->
- <#if totalPages <= 7>
- <#if totalPages gt 1>
- <#list 1..totalPages-1 as pageIndex>
- <a class="page-numbers <#if number == pageIndex>current</#if>" href="${prefix}/page/${pageIndex}">
- <span class="screen-reader-text">第 </span>${pageIndex}<span class="screen-reader-text"> 页</span>
- </a>
- </#list>
- </#if>
- <#--总页数大于7,部分以...显示-->
- <#else>
- <#--首页-->
- <#if first>
- <span class="page-numbers current">
- <span class="screen-reader-text">第 </span>1<span class="screen-reader-text"> 页</span>
- </span>
- <#else>
- <a class="page-numbers" href="${prefix}/page/1">
- <span class="screen-reader-text">第 </span>1<span class="screen-reader-text"> 页</span>
- </a>
- </#if>
- <#--当前页面小于等于4-->
- <#if number <= 3 >
- <#list 2..5 as pageIndex>
- <#if number == pageIndex>
- <span class="page-numbers current">
- <span class="screen-reader-text">第 </span>${pageIndex}<span
- class="screen-reader-text"> 页</span>
- </span>
- <#else>
- <a class="page-numbers" href="${prefix}/page/${pageIndex}">
- <span class="screen-reader-text">第 </span>${pageIndex}<span class="screen-reader-text"> 页</span>
- </a>
- </#if>
- </#list>
- <span class="page-numbers dots">…</span>
- </#if>
- <#--最后一页与当前页面之差,小于等于3-->
- <#if (totalPages - number ) <= 4 >
- <span class="page-numbers dots">…</span>
- <#list (totalPages - 4)..(totalPages - 1) as pageIndex2>
- <#if number == pageIndex2>
- <span class="page-numbers current">
- <span class="screen-reader-text">第 </span>${pageIndex2}<span
- class="screen-reader-text"> 页</span>
- </span>
- <#else>
- <a class="page-numbers" href="${prefix}/page/${pageIndex2}">
- <span class="screen-reader-text">第 </span>${pageIndex2}<span
- class="screen-reader-text"> 页</span>
- </a>
- </#if>
- </#list>
- </#if>
- <#--最后一页与当前页面之差大于3,且当前页面大于4-->
- <#if (number > 3) && ((totalPages - number) > 4 )>
- <span class="page-numbers dots">…</span>
- <a class="page-numbers" href="${prefix}/page/${number}/">
- <span class="screen-reader-text">第 </span>${number}<span class="screen-reader-text"> 页</span>
- </a>
- <span class="page-numbers current">
- <span class="screen-reader-text">第 </span>${number+1}<span class="screen-reader-text"> 页</span>
- </span>
- <a class="page-numbers" href="${prefix}/page/${number+2}">
- <span class="screen-reader-text">第 </span>${number+2}<span class="screen-reader-text"> 页</span>
- </a>
- <span class="page-numbers dots">…</span>
- </#if>
- </#if>
- <#--尾页-->
- <a class="page-numbers <#if number == totalPages>current</#if>" href="${prefix}/page/${totalPages}">
- <span class="screen-reader-text">第 </span>${totalPages}<span class="screen-reader-text"> 页</span>
- </a>
- <#--下一页-->
- <#if hasNext>
- <a class="next page-numbers" href="${prefix}/page/${number+1}">
- <i class="fa fa-angle-right"></i>
- </a>
- </#if>
- </div>
- </nav>
效果如下
- 如果页数小于等于7,会全部显示
- 如果页数大于7,中间的会以...显示,如下
2021年01月18日 09:20:56
大佬,这个有什么实现原理吗? 具体一点的,page类是我自己写还是直接用mybatis-plus?
2021年01月18日 09:29:08
@mckola_molas:你看导入的包就知道啊,用mybatis plus的
2021年01月18日 09:37:56
@言曌:okok谢谢大佬,这个是我没有仔细看导致的,不过postservice我真的没有找到啊啊啊啊啊 秋梨膏帮忙给个思路
2020年02月20日 19:45:18
大佬,我用SpringBoot+MyBatistPlus,在全局配置id-type: 0,为什么不生效呢?