MyBatis Generator实现MySQL分页插件,新增插件PaginationPlugin方法

MyBatis Generator本身是有分页功能,废话不多说,让我们先看看他是怎么实现的:

我使用的Generator

MyBatis Generator实现MySQL分页插件,新增插件PaginationPlugin方法

配置文件generatorConfig.xm:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
  PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
  "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
	<context id="testTables" targetRuntime="MyBatis3">
	
		<!-- JavaBean 实现 序列化 接口 -->
		<plugin type="org.mybatis.generator.plugins.SerializablePlugin">
		</plugin>
		<!-- genenat entity时,生成toString -->
        <plugin type="org.mybatis.generator.plugins.ToStringPlugin" />
        <!-- 自定义查询指定字段  -->
        <plugin type="org.mybatis.generator.plugins.field.FieldsPlugin" />
        
         <!-- 开启支持limit分页  -->
        <plugin type="org.mybatis.generator.plugins.page.PaginationPlugin" />
        <!-- 开启支持内存分页   可生成 支持内存分布的方法及参数  -->
        <plugin type="org.mybatis.generator.plugins.RowBoundsPlugin" />
        
        <!-- generate entity时,生成hashcode和equals方法-->
		<plugin type="org.mybatis.generator.plugins.EqualsHashCodePlugin" />
		 
		<!-- 此处是将Example改名为Criteria 当然 想改成什么都行~    -->      
        <plugin type="org.mybatis.generator.plugins.RenameExampleClassPlugin">  
	        <property name="searchString" value="Example$" />
	        <!-- 替换后
	        <property name="replaceString" value="Criteria" />  
	         
	        <property name="replaceString" value="Query" />
	        -->
        </plugin>  
		<!-- 此处是将UserMapper.xml改名为UserDao.xml 当然 想改成什么都行~ --> 
        <plugin type="org.mybatis.generator.plugins.rename.RenameSqlMapperPlugin">  
	         <property name="searchString" value="Mapper$" /> 
	        <property name="replaceString" value="Dao" />
        </plugin>  
		<!-- 此处是将UserMapper改名为UserDao 接口 当然 想改成什么都行~  -->   
        <plugin type="org.mybatis.generator.plugins.rename.RenameJavaMapperPlugin">  
	         <property name="searchString" value="Mapper$" /> 
	        <property name="replaceString" value="Dao" />
        </plugin>  
 
		
		<commentGenerator type="org.mybatis.generator.plugins.comment.MyCommentGenerator">
			<!-- 是否去除自动生成的注释 true:是 : false:否 -->
			<property name="suppressAllComments" value="false" />
			
		</commentGenerator>
		
		<!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
		<jdbcConnection driverClass="com.mysql.jdbc.Driver"
			connectionURL="jdbc:mysql://localhost:3306/test" userId="root"
			password="root">
		</jdbcConnection>
		<!-- <jdbcConnection driverClass="oracle.jdbc.OracleDriver"
			connectionURL="jdbc:oracle:thin:@127.0.0.1:1521:yycg" 
			userId="yycg"
			password="yycg">
		</jdbcConnection> -->

		<!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和 
			NUMERIC 类型解析为java.math.BigDecimal -->
		<javaTypeResolver>
			<property name="forceBigDecimals" value="false" />
		</javaTypeResolver>


		<!-- targetProject:生成PO类的位置 -->
		<javaModelGenerator targetPackage="com.yitian.pojo"
			targetProject=".\src">
			<!-- enableSubPackages:是否让schema作为包的后缀 -->
			<property name="enableSubPackages" value="false" />
			<!-- 从数据库返回的值被清理前后的空格 -->
			<property name="trimStrings" value="true" />
		</javaModelGenerator>

        <!-- targetProject:mapper映射文件生成的位置 -->
		<sqlMapGenerator targetPackage="com.yitian.mapper" 
			targetProject=".\src">
			<!-- enableSubPackages:是否让schema作为包的后缀 -->
			<property name="enableSubPackages" value="false" />
		</sqlMapGenerator>
		<!-- targetPackage:mapper接口生成的位置 -->
		<javaClientGenerator type="XMLMAPPER"
			targetPackage="com.yitian.mapper" 
			targetProject=".\src">
			<!-- enableSubPackages:是否让schema作为包的后缀 -->
			<property name="enableSubPackages" value="true" />
		</javaClientGenerator>
		

		<!-- 指定数据库表 -->
		<table schema="" tableName="A" domainObjectName="Ainfo">
		<columnOverride column="id" javaType="java.lang.Integer"></columnOverride><!-- 指定id类型 -->
		</table>
	</context>
</generatorConfiguration>

旧 RowBoundsPlugin:

generatorConfig.xml配置自带的分页功能

  <!-- 开启支持内存分页   可生成 支持内存分布的方法及参数  -->
        <plugin type="org.mybatis.generator.plugins.RowBoundsPlugin" />

运行主函数生成

int offset = 100;
int limit = 25;
RowBounds rowBounds = new RowBounds(offset, limit);
List<T> list = TMapper.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来实现分页

新 PaginationPlugin:

实现过程:

首先创建我们的实现代码

package org.mybatis.generator.plugins.page;
import java.util.List;

import org.mybatis.generator.api.CommentGenerator;
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.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;
 
/**
 * <P>File name : PaginationPlugin.java </P>
 * <P>Author : fly </P> 
 * <P>Date : 2013-7-2 上午11:50:45 </P>
 * <P>Extent:2018 yitianRen
 *    添加注释,方便理解和实现更多功能
 */
public class PaginationPlugin extends PluginAdapter {
    @Override
    public boolean modelExampleClassGenerated(TopLevelClass topLevelClass,
            IntrospectedTable introspectedTable) {
        // add field, getter, setter for limit clause
    	addPageNo(topLevelClass, introspectedTable, "pageNo");//当前页
        addStartRow(topLevelClass, introspectedTable, "startRow");//开始行
        addPageSize(topLevelClass, introspectedTable, "pageSize");//每页行数
        return super.modelExampleClassGenerated(topLevelClass,
                introspectedTable);
    }
    /**
     * 添加查询分页功能
     */
    @Override
    public boolean sqlMapSelectByExampleWithoutBLOBsElementGenerated(
            XmlElement element, IntrospectedTable introspectedTable) {
//        XmlElement isParameterPresenteElemen = (XmlElement) element
//                .getElements().get(element.getElements().size() - 1);
        XmlElement isNotNullElement = new XmlElement("if"); //$NON-NLS-1$  if标签
        //test="startRow != null" sql语句
        isNotNullElement.addAttribute(new Attribute("test", "startRow != null")); //$NON-NLS-1$ //$NON-NLS-2$  
//        isNotNullElement.addAttribute(new Attribute("compareValue", "0")); //$NON-NLS-1$ //$NON-NLS-2$
        isNotNullElement.addElement(new TextElement("limit #{startRow} , #{pageSize}"));
//        isParameterPresenteElemen.addElement(isNotNullElement);
        element.addElement(isNotNullElement);
        return super.sqlMapUpdateByExampleWithoutBLOBsElementGenerated(element, introspectedTable);
    }
    private void addStartRow(TopLevelClass topLevelClass,
            IntrospectedTable introspectedTable, String name) {
        CommentGenerator commentGenerator = context.getCommentGenerator();
        Field field = new Field();
        field.setVisibility(JavaVisibility.PROTECTED);
//        field.setType(FullyQualifiedJavaType.getIntInstance());
        field.setType(PrimitiveTypeWrapper.getIntegerInstance());
        field.setName(name);
//        field.setInitializationString("-1");
        commentGenerator.addFieldComment(field, introspectedTable);
        topLevelClass.addField(field);
        char c = name.charAt(0);
        String camel = Character.toUpperCase(c) + name.substring(1);
        Method method = new Method();
        method.setVisibility(JavaVisibility.PUBLIC);
        method.setName("set" + camel);
        method.addParameter(new Parameter(PrimitiveTypeWrapper.getIntegerInstance(), name));
        method.addBodyLine("this." + name + "=" + name + ";");
        commentGenerator.addGeneralMethodComment(method, introspectedTable);
        topLevelClass.addMethod(method);
        method = new Method();
        method.setVisibility(JavaVisibility.PUBLIC);
        method.setReturnType(PrimitiveTypeWrapper.getIntegerInstance());
        method.setName("get" + camel);
        method.addBodyLine("return " + name + ";");
        commentGenerator.addGeneralMethodComment(method, introspectedTable);
        topLevelClass.addMethod(method);
    }
    private void addPageSize(TopLevelClass topLevelClass,
    		IntrospectedTable introspectedTable, String name) {
    	CommentGenerator commentGenerator = context.getCommentGenerator();
    	Field field = new Field();
    	field.setVisibility(JavaVisibility.PROTECTED);
//        field.setType(FullyQualifiedJavaType.getIntInstance());
    	field.setType(PrimitiveTypeWrapper.getIntegerInstance());
    	field.setName(name);
        field.setInitializationString("10");
    	commentGenerator.addFieldComment(field, introspectedTable);
    	topLevelClass.addField(field);
    	char c = name.charAt(0);
    	String camel = Character.toUpperCase(c) + name.substring(1);
    	Method method = new Method();
    	method.setVisibility(JavaVisibility.PUBLIC);
    	method.setName("set" + camel);
    	method.addParameter(new Parameter(PrimitiveTypeWrapper.getIntegerInstance(), name));
    	method.addBodyLine("this." + name + "=" + name + ";");
    	//this.startRow = (pageNo-1)*this.pageSize;
        method.addBodyLine("this.startRow = (pageNo-1)*this." + name + ";");
    	commentGenerator.addGeneralMethodComment(method, introspectedTable);
    	topLevelClass.addMethod(method);
    	method = new Method();
    	method.setVisibility(JavaVisibility.PUBLIC);
    	method.setReturnType(PrimitiveTypeWrapper.getIntegerInstance());
    	method.setName("get" + camel);
    	method.addBodyLine("return " + name + ";");
    	commentGenerator.addGeneralMethodComment(method, introspectedTable);
    	topLevelClass.addMethod(method);
    }
    private void addPageNo(TopLevelClass topLevelClass,
    		IntrospectedTable introspectedTable, String name) {
    	CommentGenerator commentGenerator = context.getCommentGenerator();
    	Field field = new Field();
    	field.setVisibility(JavaVisibility.PROTECTED);
//        field.setType(FullyQualifiedJavaType.getIntInstance());
    	field.setType(PrimitiveTypeWrapper.getIntegerInstance());
    	field.setName(name);
        field.setInitializationString("1");
    	commentGenerator.addFieldComment(field, introspectedTable);
    	topLevelClass.addField(field);
    	char c = name.charAt(0);
    	String camel = Character.toUpperCase(c) + name.substring(1);
    	Method method = new Method();
    	method.setVisibility(JavaVisibility.PUBLIC);
    	method.setName("set" + camel);
    	method.addParameter(new Parameter(PrimitiveTypeWrapper.getIntegerInstance(), name));
    	method.addBodyLine("this." + name + "=" + name + ";");
    	method.addBodyLine("this.startRow = (" + name + "-1)*this.pageSize;");
    	commentGenerator.addGeneralMethodComment(method, introspectedTable);
    	topLevelClass.addMethod(method);
    	method = new Method();
    	method.setVisibility(JavaVisibility.PUBLIC);
    	method.setReturnType(PrimitiveTypeWrapper.getIntegerInstance());
    	method.setName("get" + camel);
    	method.addBodyLine("return " + name + ";");
    	commentGenerator.addGeneralMethodComment(method, introspectedTable);
    	topLevelClass.addMethod(method);
    }
    /**
     * This plugin is always valid - no properties are required
     * 这个插件总是有效的——不需要属性
     */
    public boolean validate(List<String> warnings) {
        return true;
    }
 
}

 

配置:MyBatis Generator实现MySQL分页插件,新增插件PaginationPlugin方法

运行主函数:

你会看到我们的Example类中多了三个字段,就是我们最开始分页使用的一些参数

public class AinfoExample {
    protected String orderByClause;

    protected boolean distinct;

    protected List<Criteria> oredCriteria;

    protected String fields;

    protected Integer pageNo = 1;//当前页

    protected Integer startRow;//开始位置

    protected Integer pageSize = 10;//每页大小
......

Mapper.xml中:

MyBatis Generator实现MySQL分页插件,新增插件PaginationPlugin方法

使用limit分页完成

还有另一种实现方式感觉也不错,可能习惯了 以前的分页的方式还没有尝试,链接:https://blog.csdn.net/wo240/article/details/52576711