前言

MyBatisGenerator是一个非常方便的代码生成工具,它能够根据表结构生成CRUD代码,可以满足大部分需求。但是唯一让人不爽的是,生成的代码中的数据库查询没有分页功能。本文介绍如何让MyBatis Generator生成的代码具有分页功能。一键获取MyBatis-MYSQL相关试题。

MyBatis Generator结合Maven的配置和使用

在实现分页之前,首先简单介绍MyBatis Generator如何使用。

MyBatis Generator配置文件

MyBatis Generator通常会有一个xml配置文件,用来指定连接的数据库、哪些表、如何生成代码。详情可以参考官方文档:http://www.mybatis.org/generator/configreference/xmlconfig.html 。下面给出一份简单的配置,文件命名为generatorConfig.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfigurationPUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN""http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"><generatorConfiguration><context id="mysqlgenerator" targetRuntime="MyBatis3"><jdbcConnection driverClass="com.mysql.jdbc.Driver"connectionURL="jdbc:mysql://localhost:3306/yourdb?useUnicode=true&amp;characterEncoding=UTF-8"userId="user" password="password" /><javaModelGenerator targetPackage="com.xxg.bean" targetProject="src/main/java" /><sqlMapGenerator targetPackage="com.xxg.mapper" targetProject="src/main/resources" /><javaClientGenerator type="XMLMAPPER" targetPackage="com.xxg.mapper" targetProject="src/main/java" /><table tableName="table_a" /><table tableName="table_b" /><table tableName="table_c" /><table tableName="table_d" /></context>
</generatorConfiguration>

Maven配置

官网文档中提供了四种MyBatis Generator生成代码的运行方式:命令行、使用Ant、使用Maven、Java编码。本文采用Maven插件mybatis-generator-maven-plugin来运行MyBatis Generator,详细配置同样可以参考官方文档:http://www.mybatis.org/generator/running/runningWithMaven.html 。下面给出一份简单的pom.xml的配置:

<build> <plugins> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.2</version> <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.34</version> </dependency> </dependencies> <configuration> <overwrite>true</overwrite> </configuration> </plugin> </plugins> </build>

以上配置完成后,可以通过运行mvn mybatis-generator:generate命令来生成代码。当然,如果只有上面的这些配置,生成的代码是不支持分页的。

RowBoundsPlugin

MyBatis Generator可以通过插件机制来扩展其功能,其中RowBoundsPlugin是MyBatis Generator中自带的一个分页插件。可以在MyBatis Generator配置文件generatorConfig.xml中添加这个插件:

<context id="mysqlgenerator" targetRuntime="MyBatis3"> <plugin type="org.mybatis.generator.plugins.RowBoundsPlugin"></plugin> ... </context>

再次运行mvn mybatis-generator:generate生成代码,此时会发现生成的Mapper中会加入一个新的方法:selectByExampleWithRowbounds(XxxExample example, RowBounds rowBounds),可以在代码中调用这个方法来实现分页:

int offset = 100; int limit = 25; RowBounds rowBounds = new RowBounds(offset, limit); List<Xxx> list = xxxMapper.selectByExampleWithRowbounds(example, rowBounds);

RowBounds的构造方法new RowBounds(offset, limit)中的offset、limit参数就相当于MySQL的select语句limit后的offset和rows。如果此时仔细观察一下日志打出来的SQL语句或者看下生成的XxxMapper.xml文件中的selectByExampleWithRowbounds元素,可以发现select语句并没有使用limit。实际上RowBounds原理是通过ResultSet的游标来实现分页,也就是并不是用select语句的limit分页而是用Java代码分页,查询语句的结果集会包含符合查询条件的所有数据,使用不慎会导致性能问题,所以并不推荐使用RowBoundsPlugin来实现分页。

limit分页插件实现

在实现MySQL分页时更推荐使用select语句的limit来实现分页,然而MyBatis Generator目前并没有提供这样的插件。好在MyBatis Generator支持插件扩展,我们可以自己实现一个基于limit来分页的插件。如何实现一个插件可以参考官方文档:http://www.mybatis.org/generator/reference/pluggingIn.html 。

实现思路

在生成的XxxExample中加入两个属性limit和offset,同时加上set和get方法。也就是需要生成以下代码:

private Integer limit; private Integer offset; public void setLimit(Integer limit) { this.limit = limit; } public Integer getLimit() { return limit; } public void setOffset(Integer offset) { this.offset = offset; } public Integer getOffset() { return offset; }

XxxMapper.xml中在通过selectByExample查询时,添加limit:

<select id="selectByExample" parameterType="com.xxg.bean.XxxExample" resultMap="BaseResultMap"> ... <if test="limit != null"> <if test="offset != null"> limit ${offset}, ${limit} </if> <if test="offset == null"> limit ${limit} </if> </if> </select>

插件实现代码

package com.xxg.mybatis.plugins; import java.util.List; import org.mybatis.generator.api.IntrospectedTable; import org.mybatis.generator.api.PluginAdapter; import org.mybatis.generator.api.dom.java.Field; import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType; import org.mybatis.generator.api.dom.java.JavaVisibility; import org.mybatis.generator.api.dom.java.Method; import org.mybatis.generator.api.dom.java.Parameter; import org.mybatis.generator.api.dom.java.PrimitiveTypeWrapper; import org.mybatis.generator.api.dom.java.TopLevelClass; import org.mybatis.generator.api.dom.xml.Attribute; import org.mybatis.generator.api.dom.xml.TextElement; import org.mybatis.generator.api.dom.xml.XmlElement; public class MySQLLimitPlugin extends PluginAdapter { @Override public boolean validate(List<String> list) { return true; } /** * 为每个Example类添加limit和offset属性已经set、get方法 */ @Override public boolean modelExampleClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) { PrimitiveTypeWrapper integerWrapper = FullyQualifiedJavaType.getIntInstance().getPrimitiveTypeWrapper(); Field limit = new Field(); limit.setName("limit"); limit.setVisibility(JavaVisibility.PRIVATE); limit.setType(integerWrapper); topLevelClass.addField(limit); Method setLimit = new Method(); setLimit.setVisibility(JavaVisibility.PUBLIC); setLimit.setName("setLimit"); setLimit.addParameter(new Parameter(integerWrapper, "limit")); setLimit.addBodyLine("this.limit = limit;"); topLevelClass.addMethod(setLimit); Method getLimit = new Method(); getLimit.setVisibility(JavaVisibility.PUBLIC); getLimit.setReturnType(integerWrapper); getLimit.setName("getLimit"); getLimit.addBodyLine("return limit;"); topLevelClass.addMethod(getLimit); Field offset = new Field(); offset.setName("offset"); offset.setVisibility(JavaVisibility.PRIVATE); offset.setType(integerWrapper); topLevelClass.addField(offset); Method setOffset = new Method(); setOffset.setVisibility(JavaVisibility.PUBLIC); setOffset.setName("setOffset"); setOffset.addParameter(new Parameter(integerWrapper, "offset")); setOffset.addBodyLine("this.offset = offset;"); topLevelClass.addMethod(setOffset); Method getOffset = new Method(); getOffset.setVisibility(JavaVisibility.PUBLIC); getOffset.setReturnType(integerWrapper); getOffset.setName("getOffset"); getOffset.addBodyLine("return offset;"); topLevelClass.addMethod(getOffset); return true; } /** * 为Mapper.xml的selectByExample添加limit */ @Override public boolean sqlMapSelectByExampleWithoutBLOBsElementGenerated(XmlElement element, IntrospectedTable introspectedTable) { XmlElement ifLimitNotNullElement = new XmlElement("if"); ifLimitNotNullElement.addAttribute(new Attribute("test", "limit != null")); XmlElement ifOffsetNotNullElement = new XmlElement("if"); ifOffsetNotNullElement.addAttribute(new Attribute("test", "offset != null")); ifOffsetNotNullElement.addElement(new TextElement("limit ${offset}, ${limit}")); ifLimitNotNullElement.addElement(ifOffsetNotNullElement); XmlElement ifOffsetNullElement = new XmlElement("if"); ifOffsetNullElement.addAttribute(new Attribute("test", "offset == null")); ifOffsetNullElement.addElement(new TextElement("limit ${limit}")); ifLimitNotNullElement.addElement(ifOffsetNullElement); element.addElement(ifLimitNotNullElement); return true;
}}

插件的使用

在MyBatis Generator配置文件中配置plugin:

<context id="mysqlgenerator" targetRuntime="MyBatis3"><plugin type="com.xxg.mybatis.plugins.MySQLLimitPlugin"></plugin>...</context>

如果直接加上以上配置运行mvn mybatis-generator:generate肯定会出现找不到这个插件的错误:

java.lang.ClassNotFoundException: com.xxg.mybatis.plugins.MySQLLimitPlugin

为了方便大家的使用,我已经把插件打包上传到GitHub,可以在pom.xml直接依赖使用:

<pluginRepositories> <pluginRepository> <id>mybatis-generator-limit-plugin-mvn-repo</id> <url>https://raw.github.com/wucao/mybatis-generator-limit-plugin/mvn-repo/</url> </pluginRepository> </pluginRepositories> <build> <plugins> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.2</version> <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.34</version> </dependency> <dependency> <groupId>com.xxg</groupId> <artifactId>mybatis-generator-plugin</artifactId> <version>1.0.0</version> </dependency> </dependencies> <configuration> <overwrite>true</overwrite> </configuration> </plugin> </plugins> </build>

此时运行mvn mybatis-generator:generate命令可以成功生成代码。

使用生成的代码分页

XxxExample example = new XxxExample(); ... example.setLimit(10); // page size limit example.setOffset(20); // offset List<Xxx> list = xxxMapper.selectByExample(example);

以上代码运行时执行的SQL是:select … limit 20, 10。

XxxExample example = new XxxExample(); ... example.setLimit(10); // limit List<Xxx> list = xxxMapper.selectByExample(example);

以上代码运行时执行的SQL是:select … limit 10。

最后

我这边整理了一份:Mybatis核心知识点,Spring系列全家桶、Java的系统化资料:(包括Java核心知识点、面试专题和20年最新的互联网真题、电子书等)。

MyBatis Generator如何实现MYSQL分页插件相关推荐

  1. jsp mysql 分页插件_知识分享:Mybatis框架如何使用分页插件呢?

    分页插件使用的方式 修改 pom 文件,添加分页 jar 包依赖 修改 mybatis.xml 文件 UserDao 接口,UserMapper.xml 添加对应方法与实现 sql 对应 UserSe ...

  2. mysql分页插件springboot_SpringBoot--使用Mybatis分页插件

    1.导入分页插件包和jpa包 org.springframework.boot spring-boot-starter-data-jpa com.github.pagehelper pagehelpe ...

  3. Java使用lambda进行分页,SpringBoot(八):整合mybatis,通用mapper,分页插件,lambda,Logger,junit用法...

    本文作者:低调小熊猫 转载声明:自由转载-非商用-非衍生-保持署名,非商业转载请注明作者及出处,商业转载请联系作者本人qq:2696284032 整合demo 配置依赖 tk.mybatis mapp ...

  4. SpringBoot项目集成Mybatis Plus(三)分页插件

    通过代码生成后,service继承了IService接口,这样可以直接使用Mybatis Plus封装的CRUD接口进行简单的增删改查. 例如简单的根据id查询: @RestController @R ...

  5. springboot2.0.5集成mybatis(PageHelper分页插件、generator插件使用)

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/zab635590867/article ...

  6. Day137.MBG逆向工程、分页插件举例 -Mybatis

    [1]MBG逆向工程 正向工程流程: table写数据库表->javaBean对象->BookDao->dao.xml->... 逆向工程流程: 根据table数据表,逆向分析 ...

  7. MyBatis学习总结(17)——Mybatis分页插件PageHelper

    2019独角兽企业重金招聘Python工程师标准>>> 如果你也在用Mybatis,建议尝试该分页插件,这一定是最方便使用的分页插件. 分页插件支持任何复杂的单表.多表分页,部分特殊 ...

  8. MyBatis复习(八):MyBatis 分页插件 PageHelper

    PageHelper是国人开源的一款MyBatis扩展插件,可以帮助完成自动分页功能.PageHelper自动分页插件使用非常简单,如果持久层框架用的是MyBatis,建议使用该分页插件. 引入分页插 ...

  9. (转)淘淘商城系列——MyBatis分页插件(PageHelper)的使用以及商品列表展示

    http://blog.csdn.net/yerenyuan_pku/article/details/72774381 上文我们实现了展示后台页面的功能,而本文我们实现的主要功能是展示商品列表,大家要 ...

最新文章

  1. Linux下更改系统时区及时间
  2. SAP APF tile点击之后,都发生了哪些事情
  3. OAuth2,JWT,Open-ID Connect和其他令人困惑的事物
  4. linux的基础知识——模型结构和数据包的封装
  5. CSS3: 动画循环执行(带延迟)的实现
  6. 几种关系型数据库比较
  7. AI 框架部署方案之模型转换
  8. Java的强、软、弱、虚四种引用类型
  9. UDP socket编程: C++发送 | C#接收
  10. 小学生计算机基础知识课件,计算机基础知识课件(图表部份).ppt
  11. 2020深圳杯数学建模C题
  12. 日常网页bug页面收集
  13. 【Python】实现B站MP4格式音频与视频合并,ffmpeg一个命令即可
  14. 马氏距离Mahalanobis Distance实例
  15. python 写文件write(string), writelines(list) ,读文件
  16. vs添加监视快捷键_询问操作方法:监视Android移动设备使用情况,Windows键盘快捷键和修复损坏的照片...
  17. 【统计数字】数字计数
  18. 创建和使用 HTTP 中间件层
  19. 烽火算法2.0新升级,打击覆盖范围大大提升
  20. 华为OD机试用Python实现 -【寻找关键钥匙】 2023Q1A

热门文章

  1. 2022-7-7 Leetcode 844.比较含退格的字符串
  2. 计算机网络技术期末实训题库家用无线路由器配置,【计算机网络实验实训】实验6:路由器动态路由rip和ospf设置...
  3. Java原子操作类,知多少?
  4. h61 nvme硬盘_东芝RD500的正宗传人:铠侠RD10固态硬盘评测
  5. Python 从身份证中提取出生日期/性别/年龄/生肖/星座/省份/城市/城市等级/区县(2019划分标准)
  6. grpc、https、oauth2等认证专栏实战7:使用cfssl来制作证书介绍
  7. 民宿预订三国杀:木鸟进攻、途家守业、美团观望
  8. Redmine基础:中文设定方法与常见问题对应
  9. win10跨网段共享计算机,win10系统电脑之间实现跨网段共享打印机的操作办法
  10. 常用特殊符号--网络搜比PPT插入更快