mysql分页取数每一页生成xml_让MyBatis Generator产生的代码支持分页

本文提供一种方法,让MyBatis Generator产生的代码支持分页,  适用于MySQL。

分析

如果要获取分页信息,使用MySQL语句,我们需要怎么做呢?

select * from t_user limit 0 , 2

在MySQL系统中,如果要完成一个分页,我们需要指定limit的值,也就是需要指定两个数,第一个指定从什么地方开始(示例中为0);另一个指定需要获取多少条数据(示例中为2)。

问题转化

如果要使得产生的自动产生的代码具备分页功能的话,那么,Mapper对应的XML中,select语句需要多增加两个属性值,比如:

limitStart (指定从什么位置开始查找)

limitSize (指定找到多少条数据)

何处添加

上述已经提到需要两个值limitStart和limitSize,那么,我们需要添加在哪里才能有效果呢?

以t_news表为例,创建表的SQL语句如下:

CREATE TABLE `t_news` (

`news_id` int(11) NOT NULL AUTO_INCREMENT,

`title` varchar(150) NOT NULL,

`content` text NOT NULL,

`brief_intro` varchar(255) DEFAULT NULL,

`pic_url` varchar(255) DEFAULT NULL,

`news_from` varchar(100) DEFAULT NULL,

`news_author` varchar(50) DEFAULT NULL,

`news_url` varchar(255) DEFAULT NULL,

`keywords` varchar(150) DEFAULT NULL,

`meta_desc` varchar(150) DEFAULT NULL,

`create_time` datetime DEFAULT NULL,

PRIMARY KEY (`news_id`)

) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

那么,我们可以看到NewsMapper.java中查找列表数据都是通过Example来完成的。

List selectByExampleWithBLOBs(NewsExample example);

List selectByExample(NewsExample example);

其中,selectByExampleWithBLOBs方法只有当数据表中的某一列需要存储较大内容的时候,才会产生。来看一下判断是否为BLOB列的源代码吧。摘自IntrospectedColumn类。

public boolean isBLOBColumn() {

String typeName = getJdbcTypeName();

return "BINARY".equals(typeName) || "BLOB".equals(typeName) //$NON-NLS-1$ //$NON-NLS-2$

|| "CLOB".equals(typeName) || "LONGVARBINARY".equals(typeName) //$NON-NLS-1$ //$NON-NLS-2$

|| "LONGVARCHAR".equals(typeName) || "VARBINARY".equals(typeName); //$NON-NLS-1$ //$NON-NLS-2$

}

注意:

使用selectByExample方法是不会返回BLOB类型的字段,如t_news新闻表中的content内容字段。如果想返回content的值,那么,需要使用selectByExampleWithBLOBs方法。

大家可以来看看如下内容感受一下。selectByExampleWithBLOBs中包含Blob_Column_List,而selectByExample没有。

select

distinct

,

from m_news

order by ${orderByClause}

select

distinct

from m_news

order by ${orderByClause}

从上述简单分析可以看出,limitStart和limitSize添加的地方有两个:

实体类对应的Example中需要添加。

XML文件中,selectByExample和selectByExampleWithBLOBs配置需要添加limitStart和limitSize属性。

limit #{limitStart} , #{limitSize}

有了上述的分析之后,我们需要写什么就很清楚了 。

编码

Example类具备分页属性

Example中包含两个字段limitStart和limitSize,并具有Getter和Setter方法,如:

public class NewsExample {

protected Integer limitStart;

protected Integer limitSize;

public void setLimitStart(Integer limitStart) {

this.limitStart = limitStart;

}

public Integer getLimitStart() {

return limitStart;

}

public void setLimitSize(Integer limitSize) {

this.limitSize = limitSize;

}

public Integer getLimitSize() {

return limitSize;

}

//省略其它

}

增加一个私有方法addLimit用于在Example中创建字段并生成Getter和Setter方法:

private void addLimit(TopLevelClass topLevelClass,

IntrospectedTable introspectedTable, String name) {

CommentGenerator commentGenerator = context.getCommentGenerator();

/**

* 创建成员变量

* 如protected Integer limitStart;

*/

Field field = new Field();

field.setVisibility(JavaVisibility.PROTECTED);

field.setType(PrimitiveTypeWrapper.getIntegerInstance());

field.setName(name);

commentGenerator.addFieldComment(field, introspectedTable);

topLevelClass.addField(field);

/**

* 首字母大写

*/

char c = name.charAt(0);

String camel = Character.toUpperCase(c) + name.substring(1);

/**

* 添加Setter方法

*/

Method method = new Method();

method.setVisibility(JavaVisibility.PUBLIC);

method.setName("set" + camel);

method.addParameter(new Parameter(PrimitiveTypeWrapper

.getIntegerInstance(), name));

StringBuilder sb = new StringBuilder();

sb.append("this.");

sb.append(name);

sb.append(" = ");

sb.append(name);

sb.append(";");

/**

* 如 this.limitStart = limitStart;

*/

method.addBodyLine(sb.toString());

commentGenerator.addGeneralMethodComment(method, introspectedTable);

topLevelClass.addMethod(method);

/**

* 添加Getter Method 直接调用AbstractJavaGenerator的getGetter方法

*/

Method getterMethod = AbstractJavaGenerator.getGetter(field);

commentGenerator.addGeneralMethodComment(getterMethod,

introspectedTable);

topLevelClass.addMethod(getterMethod);

}

其实,产生上述的代码并不难,因为MyBatis Generator本身就是在为生成的实体类添加变量和Getter Setter方法。

如:

AbstractJavaGenerator抽象类本身就有产生Getter方法的函数,直接调用即可。

public abstract class AbstractJavaGenerator extends AbstractGenerator {

public abstract List getCompilationUnits();

public static Method getGetter(Field field) {

Method method = new Method();

method.setName(getGetterMethodName(field.getName(), field

.getType()));

method.setReturnType(field.getType());

method.setVisibility(JavaVisibility.PUBLIC);

StringBuilder sb = new StringBuilder();

sb.append("return "); //$NON-NLS-1$

sb.append(field.getName());

sb.append(';');

method.addBodyLine(sb.toString());

return method;

}

}

另外, Setter方法的实现,可以参考AbstractJavaGenerator抽象类的getJavaBeansSetter方法,如:

public Method getJavaBeansSetter(IntrospectedColumn introspectedColumn) {

FullyQualifiedJavaType fqjt = introspectedColumn

.getFullyQualifiedJavaType();

String property = introspectedColumn.getJavaProperty();

Method method = new Method();

method.setVisibility(JavaVisibility.PUBLIC);

method.setName(getSetterMethodName(property));

method.addParameter(new Parameter(fqjt, property));

context.getCommentGenerator().addSetterComment(method,

introspectedTable, introspectedColumn);

StringBuilder sb = new StringBuilder();

if (isTrimStringsEnabled() && introspectedColumn.isStringColumn()) {

sb.append("this."); //$NON-NLS-1$

sb.append(property);

sb.append(" = "); //$NON-NLS-1$

sb.append(property);

sb.append(" == null ? null : "); //$NON-NLS-1$

sb.append(property);

sb.append(".trim();"); //$NON-NLS-1$

method.addBodyLine(sb.toString());

} else {

sb.append("this."); //$NON-NLS-1$

sb.append(property);

sb.append(" = "); //$NON-NLS-1$

sb.append(property);

sb.append(';');

method.addBodyLine(sb.toString());

}

return method;

}

然后,重写modelExampleClassGenerated产生的方法,如:

@Override

public boolean modelExampleClassGenerated(TopLevelClass topLevelClass,

IntrospectedTable introspectedTable) {

addLimit(topLevelClass, introspectedTable, "limitStart");

addLimit(topLevelClass, introspectedTable, "limitSize");

return super.modelExampleClassGenerated(topLevelClass,

introspectedTable);

}

这样,Example改变就完成了。

XML文件支持分页

接下来,我们需要对产生的XML的selectByExample和selectByExampleWithBLOBs方法添加limitStart和limitSize属性。

为selectByExample添加limitStart和limitSize

/**

* 为selectByExample添加limitStart和limitSize

*/

@Override

public boolean sqlMapSelectByExampleWithoutBLOBsElementGenerated(

XmlElement element, IntrospectedTable introspectedTable) {

XmlElement isNotNullElement = new XmlElement("if");

isNotNullElement.addAttribute(new Attribute("test",

"limitStart != null and limitSize >= 0"));

isNotNullElement.addElement(new TextElement(

"limit #{limitStart} , #{limitSize}"));

element.addElement(isNotNullElement);

return super.sqlMapSelectByExampleWithoutBLOBsElementGenerated(element,

introspectedTable);

}

为selectByExampleWithBLOBs添加limitStart和limitSize

/**

* 为selectByExampleWithBLOBs添加limitStart和limitSize

*/

@Override

public boolean sqlMapSelectByExampleWithBLOBsElementGenerated(

XmlElement element, IntrospectedTable introspectedTable) {

XmlElement isNotNullElement = new XmlElement("if");

isNotNullElement.addAttribute(new Attribute("test",

"limitStart != null and limitSize >= 0"));

isNotNullElement.addElement(new TextElement(

"limit #{limitStart} , #{limitSize}"));

element.addElement(isNotNullElement);

return super.sqlMapSelectByExampleWithBLOBsElementGenerated(element,

introspectedTable);

}

MysqlPaginationPlugin类完整代码

package my.mabatis.example.plugin;

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;

import org.mybatis.generator.codegen.AbstractJavaGenerator;

/**

* MyBatis MySQL自动生成带分页插件

*

* @author wangmengjun

*

*/

public class MysqlPaginationPlugin extends PluginAdapter {

@Override

public boolean modelExampleClassGenerated(TopLevelClass topLevelClass,

IntrospectedTable introspectedTable) {

addLimit(topLevelClass, introspectedTable, "limitStart");

addLimit(topLevelClass, introspectedTable, "limitSize");

return super.modelExampleClassGenerated(topLevelClass,

introspectedTable);

}

/**

* 为selectByExample添加limitStart和limitSize

*/

@Override

public boolean sqlMapSelectByExampleWithoutBLOBsElementGenerated(

XmlElement element, IntrospectedTable introspectedTable) {

XmlElement isNotNullElement = new XmlElement("if");

isNotNullElement.addAttribute(new Attribute("test",

"limitStart != null and limitSize >= 0"));

isNotNullElement.addElement(new TextElement(

"limit #{limitStart} , #{limitSize}"));

element.addElement(isNotNullElement);

return super.sqlMapSelectByExampleWithoutBLOBsElementGenerated(element,

introspectedTable);

}

/**

* 为selectByExampleWithBLOBs添加limitStart和limitSize

*/

@Override

public boolean sqlMapSelectByExampleWithBLOBsElementGenerated(

XmlElement element, IntrospectedTable introspectedTable) {

XmlElement isNotNullElement = new XmlElement("if");

isNotNullElement.addAttribute(new Attribute("test",

"limitStart != null and limitSize >= 0"));

isNotNullElement.addElement(new TextElement(

"limit #{limitStart} , #{limitSize}"));

element.addElement(isNotNullElement);

return super.sqlMapSelectByExampleWithBLOBsElementGenerated(element,

introspectedTable);

}

private void addLimit(TopLevelClass topLevelClass,

IntrospectedTable introspectedTable, String name) {

CommentGenerator commentGenerator = context.getCommentGenerator();

/**

* 创建类成员变量 如protected Integer limitStart;

*/

Field field = new Field();

field.setVisibility(JavaVisibility.PROTECTED);

field.setType(PrimitiveTypeWrapper.getIntegerInstance());

field.setName(name);

commentGenerator.addFieldComment(field, introspectedTable);

topLevelClass.addField(field);

/**

* 首字母大写

*/

char c = name.charAt(0);

String camel = Character.toUpperCase(c) + name.substring(1);

/**

* 添加Setter方法

*/

Method method = new Method();

method.setVisibility(JavaVisibility.PUBLIC);

method.setName("set" + camel);

method.addParameter(new Parameter(PrimitiveTypeWrapper

.getIntegerInstance(), name));

StringBuilder sb = new StringBuilder();

sb.append("this.");

sb.append(name);

sb.append(" = ");

sb.append(name);

sb.append(";");

/**

* 如 this.limitStart = limitStart;

*/

method.addBodyLine(sb.toString());

commentGenerator.addGeneralMethodComment(method, introspectedTable);

topLevelClass.addMethod(method);

/**

* 添加Getter Method 直接调用AbstractJavaGenerator的getGetter方法

*/

Method getterMethod = AbstractJavaGenerator.getGetter(field);

commentGenerator.addGeneralMethodComment(getterMethod,

introspectedTable);

topLevelClass.addMethod(getterMethod);

}

public boolean validate(List warnings) {

return true;

}

}

修改自动产生代码配置文件generatorConfig.xml中的plugin。

自动产生代码,我们可以看到NewsExample.java以及NewsMapper.xml都具有limitStart和limitSize, 可以支持分页。部分相关代码如下:

package my.mybatis.generator.auto.entity;

import java.util.ArrayList;

import java.util.Date;

import java.util.List;

public class NewsExample {

/**

* This field was generated by MyBatis Generator.

* This field corresponds to the database table m_news

*

* @mbggenerated Wed Nov 09 21:39:59 CST 2016

*/

protected Integer limitStart;

/**

* This field was generated by MyBatis Generator.

* This field corresponds to the database table m_news

*

* @mbggenerated Wed Nov 09 21:39:59 CST 2016

*/

protected Integer limitSize;

/**

* This method was generated by MyBatis Generator.

* This method corresponds to the database table m_news

*

* @mbggenerated Wed Nov 09 21:39:59 CST 2016

*/

public void setLimitStart(Integer limitStart) {

this.limitStart = limitStart;

}

/**

* This method was generated by MyBatis Generator.

* This method corresponds to the database table m_news

*

* @mbggenerated Wed Nov 09 21:39:59 CST 2016

*/

public Integer getLimitStart() {

return limitStart;

}

/**

* This method was generated by MyBatis Generator.

* This method corresponds to the database table m_news

*

* @mbggenerated Wed Nov 09 21:39:59 CST 2016

*/

public void setLimitSize(Integer limitSize) {

this.limitSize = limitSize;

}

/**

* This method was generated by MyBatis Generator.

* This method corresponds to the database table m_news

*

* @mbggenerated Wed Nov 09 21:39:59 CST 2016

*/

public Integer getLimitSize() {

return limitSize;

}

//省略其它

}

select

distinct

,

from m_news

order by ${orderByClause}

limit #{limitStart} , #{limitSize}

select

distinct

from m_news

order by ${orderByClause}

limit #{limitStart} , #{limitSize}

至此,大功告成。

测试验证

创建一个用于获取分页列表的方法。

package my.mabatis.example.service;

import java.util.List;

import my.mabatis.example.util.MyBatisUtil;

import my.mybatis.generator.auto.dao.UserMapper;

import my.mybatis.generator.auto.entity.User;

import my.mybatis.generator.auto.entity.UserExample;

import my.mybatis.generator.auto.entity.UserExample.Criteria;

import org.apache.ibatis.session.SqlSession;

/**

*

* @author wangmengjun

*

*/

public class UserService {

/**

* 查找分页列表

*/

public List selectNewsByPage(int pageNo, int pageSize) {

SqlSession sqlSession = MyBatisUtil.getSqlSessionFactory()

.openSession();

try {

UserMapper userDao = sqlSession.getMapper(UserMapper.class);

/**

* 使用Example来操作

*/

UserExample example = new UserExample();

/**

* 设置limitStart和limitSize

*/

example.setLimitStart((pageNo - 1) * pageSize);

example.setLimitSize(pageSize);

return userDao.selectByExample(example);

} finally {

sqlSession.close();

}

}

}

写一个测试类,获取第一页数据,一页5条。

package my.mabatis.example.runner;

import java.util.List;

import my.mabatis.example.service.UserService;

import my.mybatis.generator.auto.entity.User;

public class Test {

public static void main(String[] args) {

UserService userService = new UserService();

/**

* 获取第一页的数据, 一页5条数据

*/

List users = userService.selectNewsByPage(1, 5);

System.out.println(users.size());

}

}

测试数据一共有三条,所以返回结果是正确的。

log4j:WARN No appenders could be found for logger (org.apache.ibatis.logging.LogFactory).

log4j:WARN Please initialize the log4j system properly.

log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.

3

如有疑问

也可以直接问我即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值