Mybatis实现物理分页
Mybatis的自带分页方法只是逻辑分页,如果数据量很大,内存会溢出,不知道为什么开源组织不在里面实现类似Hibernate的物理分页处理方法。在不改动Mybatis源代码的情况下,怎么使Mybatis支持物理分页呢?下面我们来看看。
(1)新建一个Java类Dialect.java,该类的内容如下:
package org.mybatis.extend.interceptor;
public abstract class Dialect {
public static enum Type{
MYSQL,
ORACLE
}
public abstract String getLimitString(String sql, int skipResults, int maxResults);
}
(2)新建一个Java类OracleDialect.java,该类继承Dialect 类,具体的内容如下:
package org.mybatis.extend.interceptor;
public class OracleDialect extends Dialect{
/* (non-Javadoc)
* @see org.mybatis.extend.interceptor.IDialect#getLimitString(java.lang.String, int, int)
*/
@Override
public String getLimitString(String sql, int offset, int limit) {
sql = sql.trim();
StringBuffer pagingSelect = new StringBuffer(sql.length() + 100 );
pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");
pagingSelect.append(sql);
pagingSelect.append(" ) row_ ) where rownum_ > ").append(offset).append( " and rownum_ <= ").append(offset + limit);
return pagingSelect.toString();
}
}
(3)新建一个Mybaits的拦截器PaginationInterceptor.java,实现Interceptor接口,该类的内容如下:
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)中,具体如下:
<?xml version="1.0" encoding= "UTF-8" ?>
<!DOCTYPE configuration PUBLIC
"-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties>
<property name="dialect" value= "oracle"/>
</properties>
<plugins>
<plugin interceptor="org.mybatis.extend.interceptor.PaginationInterceptor"/>
</plugins>
</configuration>
(5)使用方法同Mybatis逻辑分页一样,拦截器会自动拦截执行SQL的地方,加上分页代码:
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实现物理分页相关推荐
- mybatis 分页需要的jar包下载_牛逼哄哄的PageHelper分页插件到底牛在哪里?
你知道的越多,不知道的就越多,业余的像一棵小草! 你来,我们一起精进!你不来,我和你的竞争对手一起精进! 编辑:业余草 urlify.cn/z2IFn2 推荐:https://www.xttblog. ...
- 【高校宿舍管理系统】第二章 整合Mybatis和写CRUD的基本流程以及使用代码生成器生成Mapper等相关代码
第二章 整合Mybatis和写CRUD的基本流程以及使用代码生成器生成Mapper等相关代码 提示:本博客个为人独立博客,不是权威,仅供参考!所有思路只做交流之用!如有不足之处,望各位在评论区友善指正 ...
- PageHelper:简述对物理分页插件PageHelper的认识
PageHelper是一款好用的,开源的,免费的Mybatis第三方物理分页插件.本文简单介绍PageHelper的基本使用和配置参数的含义,重点分析PageHelper作为Mybatis分页插件的实 ...
- 这是一篇优雅的Springboot2.0使用手册
最近再研究springboot的原理?颇有收获,现在让我分享一下springboot如何使用吧~ 想要解锁更多新姿势?请访问我的博客 啥是Springboot 和书上理解的不同,我认为Springbo ...
- PageHelper分页插件的原理是什么
PageHelper是一款好用的开源免费的Mybatis第三方物理分页插件,其实我并不想加上好用两个字,但是为了表扬插件作者开源免费的崇高精神,我毫不犹豫的加上了好用一词作为赞美. 原本以为分页插件, ...
- 从零搭建自己的SpringBoot后台框架(七)
Hello大家好,本章我们添加PageHelper分页查询功能.有问题可以联系我mr_beany@163.com.另求各路大神指点,感谢 一:什么是PageHelper PageHelper是一款好用 ...
- concurrenthashmap实现原理_Mybatis:PageHelper分页插件源码及原理剖析
PageHelper是一款好用的开源免费的Mybatis第三方物理分页插件,其实我并不想加上好用两个字,但是为了表扬插件作者开源免费的崇高精神,我毫不犹豫的加上了好用一词作为赞美. 原本以为分页插件, ...
- PageHelper分页插件源码及原理剖析
摘要: com.github.pagehelper.PageHelper是一款好用的开源免费的Mybatis第三方物理分页插件. PageHelper是一款好用的开源免费的Mybatis第三方物理分页 ...
- PageHelper分页插件
PageHelper是一款好用的开源免费的Mybatis第三方物理分页插件,下面简单介绍一下其使用方式 1.添加依赖 <dependency><groupId>com.gith ...
最新文章
- ISE 14.7 调试错误笔记
- UA MATH636 信息论6 微分熵
- Apache ZooKeeper - Leader Election使用场景
- 模板匹配matchTemplate
- Jmeter BeanShell取样器操作变量(一)
- C# 如何实现记住密码功能
- 开篇、食堂管理评价系统(Android)
- DDOS入门介绍(一):DDOS简介
- oracle 终止imp,终止imp/exp和expdp/impdp进程运行的方法
- 计算机发展前沿技术——医学领域的人工智能
- 中继器的使用方法(终)
- c# winform 支付宝付款
- PHP获取自然周日期(周一~周日)
- 深入理解ES8的新特性SharedArrayBuffer
- 架构师成长之路(4)--高可用高并发架构(图谱)
- 一文带你看懂微信小程序费率怎么收
- 孙立平:绝望比贫穷更可怕(转载)
- 谷歌找邮箱插件,外贸人必备
- 触发器flip-flop
- 【AI达人创造营第二期】基于Jetson nano的餐厅自助结账系统部署