SpringBoot 整合 MyBatis Plus 基本使用和分页,FreeMarker分页渲染

avatar 2018年12月23日15:57:23 10 16987 views
博主分享免费Java教学视频,B站账号:Java刘哥 ,长期提供技术问题解决、项目定制:本站商品点此
本文主要介绍 MyBatis Plus 的使用,顺便讲一下分页。

MyBatis Plus 是基于MyBatis 做了层封装,只需要继承它的 BaseDao, 我们就不需要写很多简单的 CURD,而且mapper实现也不用写,可以说瞬间减轻了一部分工作量。而且它也自带分页插件,不需要再使用 PageHelper 了。

一、SpringBoot 2.0 整合 MyBatis Plus

  1. pom.xml
  1. <!-- mybatis-plus begin -->
  2.     <dependency>
  3.         <groupId>com.baomidou</groupId>
  4.         <artifactId>mybatisplus-spring-boot-starter</artifactId>
  5.         <version>1.0.5</version>
  6.     </dependency>
  7.     <dependency>
  8.         <groupId>com.baomidou</groupId>
  9.         <artifactId>mybatis-plus</artifactId>
  10.         <version>2.1.8</version>
  11.     </dependency>
  12.     <dependency>
  13.         <groupId>org.springframework.boot</groupId>
  14.         <artifactId>spring-boot-starter-jdbc</artifactId>
  15.     </dependency>
  16.      <!--mybatis-plus end-->



2. application.yml
  1. mybatis-plus:
  2.   mapper-locations: classpath*:/mapper/**Mapper.xml
  3.   #实体扫描,多个package用逗号或者分号分隔
  4.   typeAliasesPackage: com.liuyanzhao.sens.entity
  5.   global-config:
  6.     #主键类型  0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";
  7.     id-type: 0
  8.     #字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断"
  9.     field-strategy: 2
  10.     #驼峰下划线转换
  11.     db-column-underline: true
  12.     #刷新mapper 调试神器
  13.     refresh-mapper: true
  14.     #逻辑删除配置(下面3个配置)
  15.     logic-delete-value: 0
  16.     logic-not-delete-value: 1
  17.   configuration:
  18.     map-underscore-to-camel-case: true
  19.     cache-enabled: false

注意修改第二行的 xml 文件位置和第4行的实体包位置



3. 代码结构

注意关注 entity、mapper类 和 mapper.xml 位置,注意和上面的配置文件对应





4. MyBatis Plus 配置类
  1. package com.liuyanzhao.sens.config;
  2. import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
  3. import com.baomidou.mybatisplus.plugins.PerformanceInterceptor;
  4. import org.springframework.context.annotation.Bean;
  5. import org.springframework.context.annotation.Configuration;
  6. /**
  7.  * @author 言曌
  8.  * @date 2018/12/22 下午1:49
  9.  */
  10. @Configuration
  11. public class MybatisPlusConfig {
  12.     /***
  13.      * plus 的性能优化
  14.      * @return
  15.      */
  16.     @Bean
  17.     public PerformanceInterceptor performanceInterceptor() {
  18.         PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
  19.         /*<!-- SQL 执行性能分析,开发环境使用,线上不推荐。 maxTime 指的是 sql 最大执行时长 -->*/
  20.         performanceInterceptor.setMaxTime(1000);
  21.         /*<!--SQL是否格式化 默认false-->*/
  22.         performanceInterceptor.setFormat(true);
  23.         return performanceInterceptor;
  24.     }
  25.     /**
  26.      * mybatis-plus分页插件
  27.      */
  28.     @Bean
  29.     public PaginationInterceptor paginationInterceptor() {
  30.         return new PaginationInterceptor();
  31.     }
  32. }


二、开始使用


这里以日志类作为一个Demo演示,包含增删改查

1.实体
  1. package com.liuyanzhao.sens.entity;
  2. import com.baomidou.mybatisplus.annotations.TableId;
  3. import com.baomidou.mybatisplus.annotations.TableName;
  4. import com.baomidou.mybatisplus.enums.IdType;
  5. import lombok.Data;
  6. import java.io.Serializable;
  7. import java.util.Date;
  8. /**
  9.  * <pre>
  10.  *     操作日志
  11.  * </pre>
  12.  *
  13.  * @author : saysky
  14.  * @date : 2018/1/19
  15.  */
  16. @Data
  17. @TableName("sens_log")
  18. public class Log implements Serializable {
  19.     private static final long serialVersionUID = -2571815432301283171L;
  20.     /**
  21.      * id
  22.      */
  23.     @TableId(type = IdType.AUTO)
  24.     private Long logId;
  25.     /**
  26.      * 标题
  27.      */
  28.     private String logTitle;
  29.     /**
  30.      * 内容
  31.      */
  32.     private String logContent;
  33.     /**
  34.      * 产生日志的ip
  35.      */
  36.     private String logIp;
  37.     /**
  38.      * 产生的时间
  39.      */
  40.     private Date logCreated;
  41.     public Log() {
  42.     }
  43.     public Log(String logTitle, String logContent, String logIp, Date logCreated) {
  44.         this.logTitle = logTitle;
  45.         this.logContent = logContent;
  46.         this.logIp = logIp;
  47.         this.logCreated = logCreated;
  48.     }
  49. }



2.Mapper 类
  1. package com.liuyanzhao.sens.mapper;
  2. import com.baomidou.mybatisplus.mapper.BaseMapper;
  3. import com.baomidou.mybatisplus.plugins.pagination.Pagination;
  4. import com.liuyanzhao.sens.entity.Log;
  5. import org.apache.ibatis.annotations.Mapper;
  6. import java.util.List;
  7. /**
  8.  * 日志Mapper
  9.  * @author liuyanzhao
  10.  */
  11. @Mapper
  12. public interface LogMapper extends BaseMapper<Log> {
  13.     /**
  14.      * 查询所有
  15.      * @param pagination 分页信息
  16.      * @return List
  17.      */
  18.     List<Log> findAll(Pagination pagination);
  19.     /**
  20.      * 查询最新的五条数据
  21.      *
  22.      * @return List
  23.      */
  24.     List<Log> findTopFive();
  25.     /**
  26.      * 删除所有的记录
  27.      * @return 影响行数
  28.      */
  29.     Integer deleteAll();
  30. }

我们查看 BaseMapper,发现里面已经常用的 insert/updateById/selectById/delete/deleteById 等方法,

需要自定义的,按照传统方法添加就行了



3.Mapper xml
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3. <mapper namespace="com.liuyanzhao.sens.mapper.LogMapper">
  4.   <resultMap id="BaseResultMap" type="com.liuyanzhao.sens.entity.Log">
  5.     <id column="log_id" jdbcType="INTEGER" property="logId"/>
  6.     <result column="log_title" jdbcType="VARCHAR" property="logTitle"/>
  7.     <result column="log_content" jdbcType="VARCHAR" property="logContent"/>
  8.     <result column="log_ip" jdbcType="VARCHAR" property="logIp"/>
  9.     <result column="log_created" jdbcType="TIMESTAMP" property="logCreated"/>
  10.   </resultMap>
  11.   <sql id="all_columns">
  12.    log_id, log_title, log_content, log_ip, log_created
  13.     </sql>
  14.   <sql id="tb">`sens_log`</sql>
  15.   <sql id="all_values">
  16.         #{logId}, #{logTitle}, #{logContent}, #{logIp}, #{logCreated}
  17.     </sql>
  18.   <select id="findAll" resultMap="BaseResultMap">
  19.     SELECT
  20.     <include refid="all_columns"/>
  21.     FROM
  22.     <include refid="tb"/>
  23.   </select>
  24.   <select id="findTopFive" resultMap="BaseResultMap">
  25.     SELECT
  26.     <include refid="all_columns"/>
  27.     FROM
  28.     <include refid="tb"/>
  29.     ORDER BY log_id DESC LIMIT 5
  30.   </select>
  31.   <delete id="deleteAll">
  32.     DELETE FROM <include refid="tb"/>
  33.   </delete>
  34. </mapper>

关于增删改查的基本接口不需要写了



4.Service实现
  1. package com.liuyanzhao.sens.service.impl;
  2. import com.baomidou.mybatisplus.plugins.Page;
  3. import com.liuyanzhao.sens.entity.Log;
  4. import com.liuyanzhao.sens.mapper.LogMapper;
  5. import com.liuyanzhao.sens.service.LogService;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.stereotype.Service;
  8. import java.util.List;
  9. /**
  10.  * <pre>
  11.  *     日志业务逻辑实现类
  12.  * </pre>
  13.  *
  14.  * @author : saysky
  15.  * @date : 2018/1/19
  16.  */
  17. @Service
  18. public class LogServiceImpl implements LogService {
  19.     @Autowired(required = false)
  20.     private LogMapper logMapper;
  21.     /**
  22.      * 保存日志
  23.      *
  24.      * @param log log
  25.      * @return log
  26.      */
  27.     @Override
  28.     public Log saveByLog(Log log) {
  29.         logMapper.insert(log);
  30.         return log;
  31.     }
  32.     /**
  33.      * 根据编号移除
  34.      *
  35.      * @param logId logId
  36.      */
  37.     @Override
  38.     public void removeByLogId(Long logId) {
  39.         logMapper.deleteById(logId);
  40.     }
  41.     /**
  42.      * 移除所有日志
  43.      */
  44.     @Override
  45.     public void removeAllLog() {
  46.         logMapper.deleteAll();
  47.     }
  48.     /**
  49.      * 查询所有日志并分页
  50.      *
  51.      * @param page 分页信息
  52.      * @return Page
  53.      */
  54.     @Override
  55.     public Page<Log> findAllLog(Page<Log> page) {
  56.         return page.setRecords(logMapper.findAll(page));
  57.     }
  58.     /**
  59.      * 查询最新的五条日志
  60.      *
  61.      * @return List
  62.      */
  63.     @Override
  64.     public List<Log> findLogLatest() {
  65.         return logMapper.findTopFive();
  66.     }
  67.     /**
  68.      * 根据编号查询
  69.      *
  70.      * @param logId logId
  71.      * @return Optional
  72.      */
  73.     @Override
  74.     public Log findLogByLogId(Long logId) {
  75.         return logMapper.selectById(logId);
  76.     }
  77. }

第4个方法是分页查询,为下面的做铺垫



相信用过 MyBatis 的朋友,开始使用 MyBatis Plus 上手很快的。


三、分页


承接上面的代码,我们实现日志分页显示

1.添加配置

上面 MybatisPlusConfig 中已经添加了分页拦截器



2. Controller 层
  1. /**
  2.  * 日志分页
  3.  *
  4.  * @param model model
  5.  * @param page  当前页码
  6.  * @return 模板路径/themes/{theme}/index
  7.  */
  8. @GetMapping(value = "logs")
  9. public String index(Model model,
  10.                     @RequestParam(name = "page",required = false, defaultValue = "1") Integer page,
  11.                     @RequestParam(name = "size",required = false, defaultValue = "10") Integer size) {
  12.     //所有日志数据,分页
  13.     Page pageable = new Page(page , size);  
  14.     Page<Log> logs = postService.findPostByStatus(pageable);  
  15.     model.addAttribute("logs", logs);
  16.     return this.render("index");
  17. }

主要关注第13-14行



3.Page 类

不要导错包

分页对象主要包含以下几个重要字段

records:数据列表

total:总记录数

pages:总页数

size:页大小,一页显示多少条

current:当前页码(从第1页开始)








四、引入 FreeMarker 渲染页面


以本站首页分页样式为例

1.引入FreeMaerker
  1. <!-- freemarker依赖 -->
  2.         <dependency>
  3.             <groupId>org.springframework.boot</groupId>
  4.             <artifactId>spring-boot-starter-freemarker</artifactId>
  5.         </dependency>



2.application.yml
  1. spring:
  2.   freemarker:
  3.     allow-request-override: false
  4.     cache: false
  5.     check-template-location: true
  6.     charset: utf-8
  7.     content-type: text/html
  8.     expose-request-attributes: false
  9.     expose-session-attributes: false
  10.     expose-spring-macro-helpers: true
  11.     suffix: .ftl
  12.     settings:
  13.       auto_import: /spring.ftl as spring
  14.       template_update_delay: 0



3. html 代码部分如下
  1. <nav class="navigation pagination" role="navigation">
  2.     <h2 class="screen-reader-text">文章导航</h2>
  3.     <div class="nav-links">
  4.     <#assign totalPages = posts.pages>
  5.     <#assign totalElements = posts.total>
  6.     <#assign number = posts.current>
  7.     <#assign first = (posts.current == 1)>
  8.     <#assign last = (posts.current == posts.pages)>
  9.     <#assign hasPrevious = (posts.current > 1)>
  10.     <#assign hasNext = (posts.current < posts.pages)>
  11.     ${totalPages} ${totalElements}  ${number}
  12.     <#--上一页-->
  13.     <#if hasPrevious>
  14.         <a class="prev page-numbers" href="${prefix}/page/${number-1}">
  15.             <i class="fa fa-angle-left"></i>
  16.         </a>
  17.     </#if>
  18.     <#--总页数小于等于7全部显示-->
  19.     <#if totalPages <= 7>
  20.         <#if totalPages gt 1>
  21.             <#list 1..totalPages-1 as pageIndex>
  22.                 <a class="page-numbers <#if number == pageIndex>current</#if>" href="${prefix}/page/${pageIndex}">
  23.                     <span class="screen-reader-text">第 </span>${pageIndex}<span class="screen-reader-text"> 页</span>
  24.                 </a>
  25.             </#list>
  26.         </#if>
  27.     <#--总页数大于7,部分以...显示-->
  28.     <#else>
  29.     <#--首页-->
  30.         <#if first>
  31.             <span class="page-numbers current">
  32.                 <span class="screen-reader-text">第 </span>1<span class="screen-reader-text"> 页</span>
  33.             </span>
  34.         <#else>
  35.             <a class="page-numbers" href="${prefix}/page/1">
  36.                 <span class="screen-reader-text">第 </span>1<span class="screen-reader-text"> 页</span>
  37.             </a>
  38.         </#if>
  39.     <#--当前页面小于等于4-->
  40.         <#if number  <= 3 >
  41.             <#list 2..5 as pageIndex>
  42.                 <#if number == pageIndex>
  43.                     <span class="page-numbers current">
  44.                          <span class="screen-reader-text">第 </span>${pageIndex}<span
  45.                             class="screen-reader-text"> 页</span>
  46.                      </span>
  47.                 <#else>
  48.                     <a class="page-numbers" href="${prefix}/page/${pageIndex}">
  49.                         <span class="screen-reader-text">第 </span>${pageIndex}<span class="screen-reader-text"> 页</span>
  50.                     </a>
  51.                 </#if>
  52.             </#list>
  53.             <span class="page-numbers dots"></span>
  54.         </#if>
  55.     <#--最后一页与当前页面之差,小于等于3-->
  56.         <#if (totalPages - number ) <= 4 >
  57.             <span class="page-numbers dots"></span>
  58.             <#list (totalPages - 4)..(totalPages - 1) as pageIndex2>
  59.                 <#if number == pageIndex2>
  60.                     <span class="page-numbers current">
  61.                          <span class="screen-reader-text">第 </span>${pageIndex2}<span
  62.                             class="screen-reader-text"> 页</span>
  63.                      </span>
  64.                 <#else>
  65.                     <a class="page-numbers" href="${prefix}/page/${pageIndex2}">
  66.                         <span class="screen-reader-text">第 </span>${pageIndex2}<span
  67.                             class="screen-reader-text"> 页</span>
  68.                     </a>
  69.                 </#if>
  70.             </#list>
  71.         </#if>
  72.     <#--最后一页与当前页面之差大于3,且当前页面大于4-->
  73.         <#if (number  > 3) && ((totalPages - number) > 4 )>
  74.             <span class="page-numbers dots"></span>
  75.             <a class="page-numbers" href="${prefix}/page/${number}/">
  76.                 <span class="screen-reader-text">第 </span>${number}<span class="screen-reader-text"> 页</span>
  77.             </a>
  78.             <span class="page-numbers current">
  79.                 <span class="screen-reader-text">第 </span>${number+1}<span class="screen-reader-text"> 页</span>
  80.             </span>
  81.             <a class="page-numbers" href="${prefix}/page/${number+2}">
  82.                 <span class="screen-reader-text">第 </span>${number+2}<span class="screen-reader-text"> 页</span>
  83.             </a>
  84.             <span class="page-numbers dots"></span>
  85.         </#if>
  86.     </#if>
  87.     <#--尾页-->
  88.         <a class="page-numbers <#if number == totalPages>current</#if>" href="${prefix}/page/${totalPages}">
  89.             <span class="screen-reader-text">第 </span>${totalPages}<span class="screen-reader-text"> 页</span>
  90.         </a>
  91.     <#--下一页-->
  92.     <#if hasNext>
  93.         <a class="next page-numbers" href="${prefix}/page/${number+1}">
  94.             <i class="fa fa-angle-right"></i>
  95.         </a>
  96.     </#if>
  97.     </div>
  98. </nav>



效果如下
  • 如果页数小于等于7,会全部显示
  • 如果页数大于7,中间的会以...显示,如下
























  • 微信
  • 交流学习,资料分享
  • weinxin
  • 个人淘宝
  • 店铺名:言曌博客咨询部

  • (部分商品未及时上架淘宝)
avatar

发表评论

avatar 登录者:匿名
匿名评论,评论回复后会有邮件通知

  

已通过评论:2   待审核评论数:0
  1. avatar mckola_molas

    大佬,这个有什么实现原理吗? 具体一点的,page类是我自己写还是直接用mybatis-plus?

    • avatar 言曌

      @mckola_molas:你看导入的包就知道啊,用mybatis plus的

      • avatar mckola_molas

        @言曌:okok谢谢大佬,这个是我没有仔细看导致的,不过postservice我真的没有找到啊啊啊啊啊 秋梨膏帮忙给个思路

  2. avatar 哈哈

    大佬,我用SpringBoot+MyBatistPlus,在全局配置id-type: 0,为什么不生效呢?