Mybatis分页-利用Mybatis Generator插件生成基于数据库方言的分页语句,统计记录总数 (转)
众所周知,Mybatis本身没有提供基于数据库方言的分页功能,而是基于JDBC的游标分页,很容易出现性能问题。网上有很多分页的解决方案,不外乎是基于Mybatis本机的插件机制,通过拦截Sql做分页。但是在像Oracle这样的数据库上,拦截器生成的Sql语句没有变量绑定,而且每次语句的都要去拦截,感觉有点浪费性能。
Mybatis Generator是Mybatis的代码生成工具,可以生成大部分的查询语句。
本文提供的分页解决方案是新增Mybatis Generator插件,在用Mybatis Generator生成Mybatis代码时,直接生成基于数据库方言的Sql语句,解决Oralce等数据库的变量绑定,且无需使用Mybatis拦截器去拦截语句判断分页。
一、编写Mybatis Generator Dialect插件
- 2011 Tgwoo Inc.
- //www.tgwoo.com/
- package com.tgwoo.core.dao.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.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.TopLevelClass;
- import org.mybatis.generator.api.dom.xml.Attribute;
- import org.mybatis.generator.api.dom.xml.Document;
- import org.mybatis.generator.api.dom.xml.TextElement;
- import org.mybatis.generator.api.dom.xml.XmlElement;
- /**
- * @author pan.wei
- * @date 2011-11-30 下午08:36:11
- */
- public class OraclePaginationPlugin extends PluginAdapter {
- @Override
- public boolean modelExampleClassGenerated(TopLevelClass topLevelClass,
- // add field, getter, setter for limit clause
- "page");
- return super.modelExampleClassGenerated(topLevelClass,
- }
- @Override
- public boolean sqlMapDocumentGenerated(Document document,
- XmlElement parentElement = document.getRootElement();
- // 产生分页语句前半部分
- new XmlElement("sql");
- new Attribute("id",
- "OracleDialectPrefix"));
- new XmlElement("if");
- new Attribute("test", "page != null"));
- new TextElement(
- "select * from ( select row_.*, rownum rownum_ from ( "));
- parentElement.addElement(paginationPrefixElement);
- // 产生分页语句后半部分
- new XmlElement("sql");
- new Attribute("id",
- "OracleDialectSuffix"));
- new XmlElement("if");
- new Attribute("test", "page != null"));
- new TextElement(
- "<![CDATA[ ) row_ ) where rownum_ > #{page.begin} and rownum_ <= #{page.end} ]]>"));
- parentElement.addElement(paginationSuffixElement);
- return super.sqlMapDocumentGenerated(document, introspectedTable);
- @Override
- public boolean sqlMapSelectByExampleWithoutBLOBsElementGenerated(
- new XmlElement("include"); //$NON-NLS-1$
- new Attribute("refid", "OracleDialectPrefix"));
- 0, pageStart);
- XmlElement isNotNullElement = new XmlElement("include"); //$NON-NLS-1$
- new Attribute("refid",
- "OracleDialectSuffix"));
- return super.sqlMapUpdateByExampleWithoutBLOBsElementGenerated(element,
- }
- /**
- * @param topLevelClass
- * @param introspectedTable
- * @param name
- */
- private void addPage(TopLevelClass topLevelClass,
- topLevelClass.addImportedType(new FullyQualifiedJavaType(
- "com.tgwoo.core.dao.pojo.Page"));
- Field field = new Field();
- field.setType(new FullyQualifiedJavaType("com.tgwoo.core.dao.pojo.Page"));
- commentGenerator.addFieldComment(field, introspectedTable);
- char c = name.charAt(0);
- 1);
- new Method();
- method.setName("set" + camel);
- new Parameter(new FullyQualifiedJavaType(
- "com.tgwoo.core.dao.pojo.Page"), name));
- "this." + name + "=" + name + ";");
- topLevelClass.addMethod(method);
- new Method();
- method.setReturnType(new FullyQualifiedJavaType(
- "com.tgwoo.core.dao.pojo.Page"));
- "get" + camel);
- "return " + name + ";");
- topLevelClass.addMethod(method);
- /**
- * This plugin is always valid - no properties are required
- */
- public boolean validate(List<String> warnings) {
- return true;
- }
二、增加插件到Mybatis Generator配置文件中
- >
- <generatorConfiguration >
- <classPathEntry location="E:\work\eclipseWorkspace\myEclipse\CTSPMTS\WebRoot\WEB-INF\lib\ojdbc14.jar" />
- <context id="oracle" >
- <plugin type="org.mybatis.generator.plugins.CaseInsensitiveLikePlugin"></plugin>
- <plugin type="org.mybatis.generator.plugins.SerializablePlugin"></plugin>
- <!-- Pagination -->
- <plugin type="com.tgwoo.core.dao.plugin.OraclePaginationPlugin"></plugin>
- <commentGenerator>
- <property name="suppressDate" value="true" />
- <property name="suppressAllComments" value="true" />
- </commentGenerator>
- <jdbcConnection driverClass="oracle.jdbc.driver.OracleDriver" connectionURL="jdbc:oracle:thin:@192.168.0.2:1521:ctspmt" userId="ctspmt" password="ctspmt123" />
- <javaModelGenerator targetPackage="com.tgwoo.ctspmt.model" targetProject="CTSPMTS/src" />
- <sqlMapGenerator targetPackage="com.tgwoo.ctspmt.data" targetProject="CTSPMTS/src" />
- <javaClientGenerator targetPackage="com.tgwoo.ctspmt.data" targetProject="CTSPMTS/src" type="XMLMAPPER" /><!--
- <table schema="ctspmt" tableName="mt_e_interface_log"/>
- --><!--
- <table schema="ctspmt" tableName="mt_e_msg" />
- <table schema="ctspmt" tableName="mt_e_msg_log" />
- <table schema="ctspmt" tableName="mt_e_msg_receiver" />
- <table schema="ctspmt" tableName="st_e_org" />
- <table schema="ctspmt" tableName="st_e_role" />
- <table schema="ctspmt" tableName="st_e_user" />
- <table schema="ctspmt" tableName="mt_e_user_msg_conf" />
- <table schema="ctspmt" tableName="mt_j_user_device" />
- <table schema="ctspmt" tableName="st_j_user_role" />
- <table schema="ctspmt" tableName="ST_E_UNIQUE_KEY" />
- ><table schema="ctspmt" tableName="mt_v_msg_item" />
- </context>
- </generatorConfiguration>
三、示例
- 2011 Tgwoo Inc.
- //www.tgwoo.com/
- package com.tgwoo.ctspmt.test;
- import com.tgwoo.core.config.SpringBeanProxy;
- import com.tgwoo.core.dao.pojo.Page;
- import com.tgwoo.ctspmt.data.MtVMsgItemMapper;
- import com.tgwoo.ctspmt.model.MtVMsgItemExample;
- /**
- * @author pan.wei
- * @date 2011-11-25 下午01:26:17
- */
- public class Test {
- /**
- * @param args
- */
- public static void main(String[] args) {
- //get spring mapper instance
- MtVMsgItemMapper.class);
- new MtVMsgItemExample();
- new Page(0, 10);
- ex.createCriteria().andMsgCodeEqualTo("222");
- // set count,up to you
- int row = mapper.selectByExample(ex).size();
- "============row:" + row + "================");
- }
四、分页类
- package com.tgwoo.core.dao.pojo;
- /**
- * @author pan.wei
- * @date 2011-12-1 上午11:36:12
- */
- public class Page {
- // 分页查询开始记录位置
- private int begin;
- // 分页查看下结束位置
- private int end;
- // 每页显示记录数
- private int length;
- // 查询结果总记录数
- private int count;
- // 当前页码
- private int current;
- // 总共页数
- private int total;
- public Page() {
- /**
- * 构造函数
- *
- * @param begin
- * @param length
- */
- public Page(int begin, int length) {
- this.begin = begin;
- this.length = length;
- this.end = this.begin + this.length;
- this.current = (int) Math.floor((this.begin * 1.0d) / this.length) + 1;
- /**
- * @param begin
- * @param length
- * @param count
- */
- public Page(int begin, int length, int count) {
- this(begin, length);
- this.count = count;
- /**
- * @return the begin
- */
- public int getBegin() {
- return begin;
- /**
- * @return the end
- */
- public int getEnd() {
- return end;
- /**
- * @param end
- * the end to set
- */
- public void setEnd(int end) {
- this.end = end;
- /**
- * @param begin
- * the begin to set
- */
- public void setBegin(int begin) {
- this.begin = begin;
- if (this.length != 0) {
- this.current = (int) Math.floor((this.begin * 1.0d) / this.length) + 1;
- }
- /**
- * @return the length
- */
- public int getLength() {
- return length;
- /**
- * @param length
- * the length to set
- */
- public void setLength(int length) {
- this.length = length;
- if (this.begin != 0) {
- this.current = (int) Math.floor((this.begin * 1.0d) / this.length) + 1;
- }
- /**
- * @return the count
- */
- public int getCount() {
- return count;
- /**
- * @param count
- * the count to set
- */
- public void setCount(int count) {
- this.count = count;
- this.total = (int) Math.floor((this.count * 1.0d) / this.length);
- if (this.count % this.length != 0) {
- this.total++;
- }
- /**
- * @return the current
- */
- public int getCurrent() {
- return current;
- /**
- * @param current
- * the current to set
- */
- public void setCurrent(int current) {
- this.current = current;
- /**
- * @return the total
- */
- public int getTotal() {
- if (total == 0) {
- return 1;
- return total;
- /**
- * @param total
- * the total to set
- */
- public void setTotal(int total) {
- this.total = total;
- }
五、生成后的代码
1、Example代码
- package com.tgwoo.ctspmt.model;
- import com.tgwoo.core.dao.pojo.Page;
- import java.math.BigDecimal;
- import java.util.ArrayList;
- import java.util.Date;
- import java.util.Iterator;
- import java.util.List;
- public class MtVMsgItemExample {
- protected String orderByClause;
- protected boolean distinct;
- protected List<Criteria> oredCriteria;
- protected Page page;
- ...
2、mapper.xml
- <select id="selectByExample" resultMap="BaseResultMap" parameterType="com.tgwoo.ctspmt.model.MtVMsgItemExample" >
- <include refid="OracleDialectPrefix" />
- <if test="distinct" >
- </if>
- <include refid="Base_Column_List" />
- <if test="_parameter != null" >
- <include refid="Example_Where_Clause" />
- </if>
- <if test="orderByClause != null" >
- </if>
- <include refid="OracleDialectSuffix" />
- </select>
- <sql id="OracleDialectPrefix" >
- <if test="page != null" >
- </if>
- </sql>
- <sql id="OracleDialectSuffix" >
- <if test="page != null" >
- <![CDATA[ ) row_ ) where rownum_ > #{page.begin} and rownum_ <= #{page.end} ]]>
- </if>
- </sql>
- ...
附件是Mybatis Generatorjar包。
其他数据库的方言可以按照Oracle的去改写,有写好的希望能共享下。
-------------------------------------------------------------------------------------------------------
maven管理:
1、pom.xml
- <build>
- <plugins>
- <plugin>
- <groupId>org.mybatis.generator</groupId>
- <artifactId>mybatis-generator-maven-plugin</artifactId>
- <version>1.3.1</version>
- <executions>
- <execution>
- <id>Generate MyBatis Artifacts</id>
- <goals>
- <goal>generate</goal>
- </goals>
- </execution>
- </executions>
- <dependencies>
- <dependency>
- <groupId>com.oracle</groupId>
- <artifactId>ojdbc14</artifactId>
- <version>10.2.0.4.0</version>
- </dependency>
- </dependencies>
- </plugin>
- </plugins>
- </build>
2、generatorConfig.xml
- <?xml version="1.0" encoding="UTF-8"?>
- PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
- >
- <generatorConfiguration>
- <context id="oracleGenerator" targetRuntime="MyBatis3">
- <plugin type="org.mybatis.generator.plugins.CaseInsensitiveLikePlugin"></plugin>
- <plugin type="org.mybatis.generator.plugins.SerializablePlugin"></plugin>
- <!-- Pagination -->
- <plugin
- type="com.tgwoo.test.core.dao.mybatis.generator.plugin.pagination.OraclePaginationPlugin"></plugin>
- <!-- 取消注释 -->
- <commentGenerator>
- <property name="suppressDate" value="true" />
- <property name="suppressAllComments" value="true" />
- </commentGenerator>
- <!-- 配置连接数据信息 -->
- <jdbcConnection driverClass="oracle.jdbc.driver.OracleDriver"
- connectionURL="jdbc:oracle:thin:@192.168.0.2:1521:test" userId="test"
- password="test123" />
- <javaTypeResolver>
- <property name="forceBigDecimals" value="false" />
- </javaTypeResolver>
- <!-- 配置自动生成的Model的保存路径与其它参数 -->
- <javaModelGenerator targetPackage="com.tgwoo.test.dao.model"
- targetProject=".\src\main\java">
- <property name="enableSubPackages" value="false" />
- <property name="trimStrings" value="true" />
- </javaModelGenerator>
- <!-- 配置自动生成的Mappper.xml映射的保存路径与其它参数 -->
- <sqlMapGenerator targetPackage="com.tgwoo.test.dao"
- targetProject=".\src\main\resources">
- <property name="enableSubPackages" value="false" />
- </sqlMapGenerator>
- <!-- 配置自动生成的Mappper.java接口的保存路径与其它参数 -->
- <javaClientGenerator type="XMLMAPPER"
- targetPackage="com.tgwoo.test.dao" targetProject=".\src\main\java">
- <property name="enableSubPackages" value="false" />
- </javaClientGenerator>
- <!-- 生成表对应的操作与实体对象 -->
- <table schema="test" tableName="testTable">
- <columnOverride column="id" javaType="Long" />
- </table>
- </context>
- </generatorConfiguration>
3、run
Goals:mybatis-generator:generate
4、注意事项
报插件无法找到或者无法实例化的一般是分页插件和maven插件不在同一classloader下引起的,需要在mybatis-generator-maven-plugin的dependencies中增加dependency。
Mybatis分页-利用Mybatis Generator插件生成基于数据库方言的分页语句,统计记录总数 (转)的更多相关文章
- springboot+mybatis+mysql 利用mybatis自动生成sql语句
工具和环境 idea,mysql,JDK1.8 效果图如下 结构图如下 java resources sql文件 /* Navicat MySQL Data Transfer Source Serve ...
- thinkphp5 数据库查询之paginate: 同时获取记录总数和分页数据
thinkphp5中要想同时获得查询记录的总数量以及分页的数据, 可以用paginate(), 真的非常方便! 表结构: CREATE TABLE `t_users` ( `id` int(11) u ...
- mybatis框架下使用generator插件自动生成domain/mapping/mapper
手动去创建domain/mapping/mapper费时费力还容易出错,用插件自动生成非常的方便. 这里以MySQL数据库为例,也可以改成Oracle,改成相应的驱动和URL即可. 下载generat ...
- MyBatis使用Generator自动生成代码
MyBatis中,可以使用Generator自动生成代码,包括DAO层. MODEL层 .MAPPING SQL映射文件. 第一步: 配置好自动生成代码所需的XML配置文件,例如(generator. ...
- Ecside基于数据库的过滤、分页、排序
首先ecside展现列表.排序.过滤(该三种操作以下简称为 RSF )的实现原理完全和原版EC一样, 如果您对原版EC的retrieveRowsCallback.sortRowsCallback.fi ...
- SpringBoot入门篇--整合mybatis+generator自动生成代码+druid连接池+PageHelper分页插件
原文链接 我们这一篇博客讲的是如何整合Springboot和Mybatis框架,然后使用generator自动生成mapper,pojo等文件.然后再使用阿里巴巴提供的开源连接池druid,这个连接池 ...
- 利用mybatis的Generator的插件生成代码
1 在resources文件夹下创建generatorConfig.xml文件来做相关配置 <?xml version="1.0" encoding="UTF-8& ...
- SpringBoot 添加mybatis generator 自动生成代码插件
自动生成数据层代码,提高开发效率 1.pom添加插件,并指定配置文件路径 <!-- mybatis generator 自动生成代码插件 --> <plugin> <gr ...
- 使用mybatis generator插件,自动生成dao、dto、mapper等文件
mybatis generator 介绍 mybatis generator中文文档http://mbg.cndocs.tk/ MyBatis Generator (MBG) 是一个Mybatis的代 ...
随机推荐
- Redis ==> 集群的三种模式
一.主从同步/复制 通过持久化功能,Redis保证了即使在服务器重启的情况下也不会丢失(或少量丢失)数据,因为持久化会把内存中数据保存到硬盘上,重启会从硬盘上加载数据. 但是由于数据是存储在一台服务器 ...
- 如何用 putty 连接远程 Linux 系统
如何用 putty 连接远程 Linux 系统 Putty 简介 Putty 是一个免费的.Windows x86 平台下的 Telnet.SSH 和 Rlogin 客户端,但是功能丝毫不逊色于商业的 ...
- 【HANA系列】SAP HANA SLT 在表中隐藏字段并传入HANA的方法
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列]SAP HANA SLT在表中隐 ...
- open_basedir restriction in effect,解决php引入文件权限问题 解决方法
如下: 出现问题的原因: 查看问题描述以及资料,发现是php open_basedir 配置的问题,PHP不能引入其授权目录上级及其以上的文件: 一般情况下是不会出现这种问题的,之所以出现这个问题绝大 ...
- 分片式图片服务器fastDFS安装过程
1. 什么是FastDFS FastDFS 是用 c 语言编写的一款开源的分布式文件系统.FastDFS 为互联网量身定制, 充分考虑了冗余备份.负载均衡.线性扩容等机制,并注重高可用.高性能等指标, ...
- Linux C/C++基础 文件(中)
1.ubuntu cat命令的实现 cat——查看或者合并文件内容 #include<stdio.h> int main(int argc,char* argv[]) { //1.打开文件 ...
- Asp.NetCore应用--部署到 ubuntu 进行托管
准备过程 netcore linux发布包(本人是通过vs2017发布) ubuntu 16.0.4虚机 进行托管 ubuntu netcore发布文件路径 服务器设置为将对 http://< ...
- 用docker 跑 logstash节点 - kibana界面汉化
0.docker中logstash的配置文件 [root@VM_0_6_centos pipeline]# cat logstash.yml #http.host: "0.0.0.0&quo ...
- Elasticsearch-如何识别一篇文档
ES-识别文档 为了识别同一个索引中的某篇文档,ES使用_uid中的文档类型和ID结合体._uid字段是由_id和_type字段组成,当搜索或者检索文档的时候总是能获得这两项信息. FengZhend ...
- [转] c++加载外部库文件探究
首先介绍:用#import导入dll和用#pragma comment导入lib还有在程序中LoadLibrary加载dll有什么区别 (1) #import导入的dll是com组建的dll,主要用来 ...