分页查询在小项目的开发中基本是逃不了的,虽然有基于ThreadLocal的PageHelper插件可以直接使用,但还是想从源头解决问题。针对Mysql来说的话,其实只要在生成的Mapper和SqlMap文件中添加limit和offset就可以了。
直接上代码:
public class MySqlLimitPluginextends PluginAdapter{
@Override
public boolean validate(List<String> list){
return true;
}
/**
* 为每个Example类添加limit和offset属性已经set、get方法
* @param topLevelClass
* @param introspectedTable
* @return
*/
@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;
}
@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;
}
}
modelExampleClassGenerated
方法是在生成的Example类中添加limit和offset成员变量,以及响应的getter、setter方法。 sqlMapSelectByExampleWithoutBLOBsElementGenerated
方法是在生成的id为 selectByExample
的标签中添加limit和offset。
将插件添加到项目中,并且运行完MybatisGenerator,我们来查看下生成的相关文件:
Example类:
public class AdministratorExample{
...
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;
}
...
}
xml文件:
<selectid="selectByExample"parameterType="cn.didadu.dao.entity.AdministratorExample"resultMap="BaseResultMap">
select
<iftest="distinct">
distinct
</if>
<includerefid="Base_Column_List"/>
from administrator
<iftest="_parameter != null">
<includerefid="Example_Where_Clause"/>
</if>
<iftest="orderByClause != null">
order by ${orderByClause}
</if>
<iftest="limit != null">
<iftest="offset != null">
limit ${offset}, ${limit}
</if>
<iftest="offset == null">
limit ${limit}
</if>
</if>
</select>
可以看出成功生成了相应的limit和offset。
使用方式如下:
AdministratorExample administratorExample = new AdministratorExample(); administratorExample.setOffset(10); administratorExample.setLimit(100);
本章节就到这里了。