Mybatis的自带分页方法只是逻辑分页,如果数据量很大,内存会溢出,不知道为什么开源组织不在里面实现类似Hibernate的物理分页处理方法。在不改动Mybatis源代码的情况下,怎么使Mybatis支持物理分页呢?下面我们来看看。

(1)新建一个Java类Dialect.java,该类的内容如下:

Java代码  
  1. package org.mybatis.extend.interceptor;

  2. public  abstract  class Dialect {

  3. public  static  enum Type{

  4. MYSQL,

  5. ORACLE

  6. }

  7. public  abstract String getLimitString(String sql, int skipResults,  int maxResults);

  8. }

(2)新建一个Java类OracleDialect.java,该类继承Dialect 类,具体的内容如下:

Java代码  
  1. package org.mybatis.extend.interceptor;

  2. public  class OracleDialect  extends Dialect{

  3. /* (non-Javadoc)

  4. * @see org.mybatis.extend.interceptor.IDialect#getLimitString(java.lang.String, int, int)

  5. */

  6. @Override

  7. public String getLimitString(String sql, int offset,  int limit) {

  8. sql = sql.trim();

  9. StringBuffer pagingSelect = new StringBuffer(sql.length() +  100 );

  10. pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");

  11. pagingSelect.append(sql);

  12. pagingSelect.append(" ) row_ ) where rownum_ > ").append(offset).append( " and rownum_ <= ").append(offset + limit);

  13. return pagingSelect.toString();

  14. }

  15. }

(3)新建一个Mybaits的拦截器PaginationInterceptor.java,实现Interceptor接口,该类的内容如下:

Java代码 

package org.mybatis.extend.interceptor

import java.sql.Connection;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.apache.ibatis.executor.parameter.DefaultParameterHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.RowBounds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import platform.pages.mybatis.dialects.MysqlDialect;
import platform.pages.mybatis.dialects.OracleDialect;

/**
 * Mybaits的拦截器
 *
 * @author fhx 2013-1-27 下午03:04:33
 */
@Intercepts( { @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class }) })
public class PaginationInterceptor implements Interceptor {

protected static Logger log = LoggerFactory.getLogger(PaginationInterceptor.class);

@Override
 public Object intercept(Invocation invocation) throws Throwable {
  StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
  BoundSql boundSql2 = statementHandler.getBoundSql();
  List list = boundSql2.getParameterMappings();
  MetaObject metaStatementHandler = MetaObject.forObject(statementHandler);
  RowBounds rowBounds = (RowBounds) boundSql2.getParameterObject();
  if (rowBounds == null || rowBounds == RowBounds.DEFAULT) {
   return invocation.proceed();
  }
  String originalSql = (String) metaStatementHandler.getValue("delegate.boundSql.sql");
  Configuration configuration = (Configuration) metaStatementHandler.getValue("delegate.configuration");
  Dialect.Type databaseType = null;
  try {
   databaseType = Dialect.Type.valueOf(configuration.getVariables().getProperty("dialect").toUpperCase());
  } catch (Exception e) {
   System.out.println("mybatis-config.xml中未设置数据库类型");
  }
  if (databaseType == null) {
   throw new RuntimeException(
     "the value of the dialect property in configuration.xml is not defined : " + configuration.getVariables().getProperty("dialect"));
  }
  Dialect dialect = null;
  switch (databaseType) {
  case ORACLE: // oracle 分页
   dialect = new OracleDialect();
   break;
  case MYSQL: // MySQL分页
   dialect = new MysqlDialect();
   break;
  }
  metaStatementHandler.setValue("delegate.boundSql.sql", dialect.getLimitString(originalSql, rowBounds.getOffset(), rowBounds.getLimit()));

metaStatementHandler.setValue("delegate.rowBounds.offset",RowBounds.NO_ROW_OFFSET);

metaStatementHandler.setValue("delegate.rowBounds.limit",RowBounds.NO_ROW_LIMIT);

if (log.isDebugEnabled()) {
   BoundSql boundSql = statementHandler.getBoundSql();
   log.debug(" 生成分页SQL : " + boundSql.getSql());
  }
  return invocation.proceed();
 }

@Override
 public Object plugin(Object target) {
  return Plugin.wrap(target, this);
 }

@Override
 public void setProperties(Properties arg0) {

}

}

(4)将Mybatis的拦截器配置到Mybatis的全局配置文件(mybatis.cfg.xml)中,具体如下:

Java代码 
  1. <?xml version="1.0" encoding= "UTF-8" ?>

  2. <!DOCTYPE configuration PUBLIC

  3. "-//mybatis.org//DTD Config 3.0//EN"

  4. "http://mybatis.org/dtd/mybatis-3-config.dtd">

  5. <configuration>

  6. <properties>

  7. <property name="dialect" value= "oracle"/>

  8. </properties>

  9. <plugins>

  10. <plugin interceptor="org.mybatis.extend.interceptor.PaginationInterceptor"/>

  11. </plugins>

  12. </configuration>

(5)使用方法同Mybatis逻辑分页一样,拦截器会自动拦截执行SQL的地方,加上分页代码:

Java代码 
  1. getSqlSession().selectList(sqlId, paramMap,new RowBounds(pageId, pageSize));

(6) 和spring集成封装有superDao

public class SupperDao extends SqlSessionDaoSupport{
 
 protected Logger log = LoggerFactory.getLogger(getClass());
 
 /**
  * 保存
  * @param key
  * @param object
  */
 public void save(String key, Object object) {
  getSqlSession().insert(key, object);
 }
 
 /**
  * 删除
  * @param key
  * @param id
  */
 public void delete(String key, Serializable id) {
  getSqlSession().delete(key, id);
 }
 
 /**
  * 删除
  * @param key
  * @param object
  */
 public void delete(String key, Object object) {
  getSqlSession().delete(key, object);
 }
 
 /**
  * 查询 返回一个结果
  * @param <T>
  * @param key
  * @param params
  * @return
  */
 public <T> T get(String key, Object params) {
  return (T) getSqlSession().selectOne(key, params);
 }
 
 /**
  * 查询 返回多个结果
  * @param <T>
  * @param key
  * @return
  */
 public <T> List<T> findList(String key) {
  return getSqlSession().selectList(key);
 }
 
 /**
  * 分页查询
  * @param <T>
  * @param key
  * @param offset
  * @param pageSize
  * @return
  */
 public <T> List<T> findList(String key,int offset,int pageSize) {
  return getSqlSession().selectList(key,new RowBounds(offset, pageSize));
 }
 
 /**
  * 查询 可带参数 返回多个结果
  * @param <T>
  * @param key
  * @param params
  * @return
  */
 public <T> List<T> findList(String key, Object params) {
  return getSqlSession().selectList(key, params);
 }
 
 /**
  * 分页查询 可带参数
  * @param <T>
  * @param key
  * @param params
  * @param pageNo
  * @param pageSize
  * @return
  */
 public <T> List<T> findList(String key, Object params,int pageOffset,int pageSize) {
  return getSqlSession().selectList(key, params,new RowBounds(pageOffset, pageSize));
 }

Mybatis实现物理分页相关推荐

  1. mybatis 分页需要的jar包下载_牛逼哄哄的PageHelper分页插件到底牛在哪里?

    你知道的越多,不知道的就越多,业余的像一棵小草! 你来,我们一起精进!你不来,我和你的竞争对手一起精进! 编辑:业余草 urlify.cn/z2IFn2 推荐:https://www.xttblog. ...

  2. 【高校宿舍管理系统】第二章 整合Mybatis和写CRUD的基本流程以及使用代码生成器生成Mapper等相关代码

    第二章 整合Mybatis和写CRUD的基本流程以及使用代码生成器生成Mapper等相关代码 提示:本博客个为人独立博客,不是权威,仅供参考!所有思路只做交流之用!如有不足之处,望各位在评论区友善指正 ...

  3. PageHelper:简述对物理分页插件PageHelper的认识

    PageHelper是一款好用的,开源的,免费的Mybatis第三方物理分页插件.本文简单介绍PageHelper的基本使用和配置参数的含义,重点分析PageHelper作为Mybatis分页插件的实 ...

  4. 这是一篇优雅的Springboot2.0使用手册

    最近再研究springboot的原理?颇有收获,现在让我分享一下springboot如何使用吧~ 想要解锁更多新姿势?请访问我的博客 啥是Springboot 和书上理解的不同,我认为Springbo ...

  5. PageHelper分页插件的原理是什么

    PageHelper是一款好用的开源免费的Mybatis第三方物理分页插件,其实我并不想加上好用两个字,但是为了表扬插件作者开源免费的崇高精神,我毫不犹豫的加上了好用一词作为赞美. 原本以为分页插件, ...

  6. 从零搭建自己的SpringBoot后台框架(七)

    Hello大家好,本章我们添加PageHelper分页查询功能.有问题可以联系我mr_beany@163.com.另求各路大神指点,感谢 一:什么是PageHelper PageHelper是一款好用 ...

  7. concurrenthashmap实现原理_Mybatis:PageHelper分页插件源码及原理剖析

    PageHelper是一款好用的开源免费的Mybatis第三方物理分页插件,其实我并不想加上好用两个字,但是为了表扬插件作者开源免费的崇高精神,我毫不犹豫的加上了好用一词作为赞美. 原本以为分页插件, ...

  8. PageHelper分页插件源码及原理剖析

    摘要: com.github.pagehelper.PageHelper是一款好用的开源免费的Mybatis第三方物理分页插件. PageHelper是一款好用的开源免费的Mybatis第三方物理分页 ...

  9. PageHelper分页插件

    PageHelper是一款好用的开源免费的Mybatis第三方物理分页插件,下面简单介绍一下其使用方式 1.添加依赖 <dependency><groupId>com.gith ...

最新文章

  1. ISE 14.7 调试错误笔记
  2. UA MATH636 信息论6 微分熵
  3. Apache ZooKeeper - Leader Election使用场景
  4. 模板匹配matchTemplate
  5. Jmeter BeanShell取样器操作变量(一)
  6. C# 如何实现记住密码功能
  7. 开篇、食堂管理评价系统(Android)
  8. DDOS入门介绍(一):DDOS简介
  9. oracle 终止imp,终止imp/exp和expdp/impdp进程运行的方法
  10. 计算机发展前沿技术——医学领域的人工智能
  11. 中继器的使用方法(终)
  12. c# winform 支付宝付款
  13. PHP获取自然周日期(周一~周日)
  14. 深入理解ES8的新特性SharedArrayBuffer
  15. 架构师成长之路(4)--高可用高并发架构(图谱)
  16. 一文带你看懂微信小程序费率怎么收
  17. 孙立平:绝望比贫穷更可怕(转载)
  18. 谷歌找邮箱插件,外贸人必备
  19. 触发器flip-flop
  20. 【AI达人创造营第二期】基于Jetson nano的餐厅自助结账系统部署

热门文章

  1. 突出告警信息(DBA_OUTSTANDING_ALERTS)
  2. 通过ssh建立点对点的隧道,实现两个子网通信
  3. 中国人工智能学会通讯——机器人组件技术在智能制造系统中的应用
  4. 《Android程序设计》一第一部分 工具和基础
  5. Intellij IDEA中的Mybatis Plugin破解
  6. handler消息机制
  7. IP地址分类及子网掩码详解
  8. Tempter of the Bone(DFS + 奇偶剪枝,好题)
  9. 20101029总结
  10. Nessus Scan