mysql ibatis 分页_MyBatis怎样实现MySQL动态分页?
/**
* 模糊查询(分页)
*
* @project apqp
* @author liud JIRA:APQP-23
* @date 2013-04-16
* @param flow
* @param page
* 分页参数包装器
* @return pageData 分页结果集
* @history
*/
@Override
public PageData queryFlow(Attach attach, Pagination page) {
if (page.isReadTotal())
page.setTotal(this.selectOneByTotalCount("flow.queryList", attach));
RowBounds rowbounds = new RowBounds(page.getStart(), page.getLimit());
List result = this.sqlSession.selectList("flow.queryList",
attach, rowbounds);
PageData pageData = new PageData();
pageData.setResult(result);
pageData.setPagination(page);
return pageData;
}
/**
* 获得分页的总条数
*
* @author liud
* @date 2013-2-18
* @param s
* mybatis对应的命名空间
* @param obj
* 参数
* @return
*/
protected int selectOneByTotalCount(String s, Object obj) {
final BaseEntity baseEntity = new BaseEntity();
RowBounds rowbounds = new RowBounds(-1, -1);
this.sqlSession.select(s, obj, rowbounds, new ResultHandler() {
@Override
public void handleResult(ResultContext context) {
Object object = context.getResultObject();
if (object != null) {
BaseEntity base = (BaseEntity) object;
baseEntity.setTotal(base.getTotal());
}
}
});
return baseEntity.getTotal();
}
-- mybatis.xml flow.queryList
parameterType="com.eman.flow.entity.Attach">
SELECT f1.fileID
, f1.fileName
, f1.fileType
, f1.fileSize
, f1.uploadUser
, f1.uploadTime
, f2.userName uploadUserName
FROM
t_attachmentOfAPQPFlowPhase p INNER
JOIN t_attachment f1
ON p.fileID =
f1.fileID
INNER JOIN t_user f2 ON f1.uploadUser =
f2.userID
WHERE
p.phaseID = #{phaseID}
order by f1.uploadTime desc
-- mybatis.config.xml
/p>
"http://mybatis.org/dtd/mybatis-3-config.dtd">
package com.eman.core.interceptor;
import java.sql.Connection;
import java.util.Properties;
import org.apache.ibatis.executor.statement.StatementHandler;
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 com.eman.core.dialect.Dialect;
import com.eman.core.dialect.SQLServer2005Dialect;
import com.eman.core.dialect.SQLServer2008Dialect;
/**
* 拦截mybatis执行sql,以用于转换分页sql
*
* @author liud
*
*/
@Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class }) })
public class PaginationInterceptor implements Interceptor {
private static final Logger log = LoggerFactory.getLogger("controller");
@Override
public Object intercept(Invocation invocation) throws Throwable {
StatementHandler sh = (StatementHandler) invocation.getTarget();
MetaObject mo = MetaObject.forObject(sh);
RowBounds rb = (RowBounds) mo.getValue("delegate.rowBounds");
if (rb == RowBounds.DEFAULT
|| (rb.getLimit() <= 0 && rb.getLimit() != -1)
|| rb.getLimit() > RowBounds.NO_ROW_LIMIT)
return invocation.proceed();
Configuration conf = (Configuration) mo
.getValue("delegate.configuration");
Dialect dialect = this.invokeDialect(conf.getVariables()
.getProperty("jdbc.db.type").toUpperCase());
if (dialect == null)
return invocation.proceed();
String bSql = (String) mo.getValue("delegate.boundSql.sql");
if (rb.getLimit() == -1 && rb.getOffset() == -1)
bSql = dialect.getTotalString(bSql);
else
bSql = dialect.getLimitString(bSql, rb.getOffset(), rb.getLimit());
mo.setValue("delegate.boundSql.sql", bSql);
mo.setValue("delegate.rowBounds.offset", RowBounds.NO_ROW_OFFSET);
mo.setValue("delegate.rowBounds.limit", RowBounds.NO_ROW_LIMIT);
return invocation.proceed();
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
}
/**
* 通过配置获得sql数据库对象
*
* @author liud
* @date 2013-2-18
* @param param
* @return
*/
private Dialect invokeDialect(String param) {
Dialect.Type type = null;
try {
type = Dialect.Type.valueOf(param);
} catch (Exception e) {
log.debug(
"the value of the dialect property in mybatis-config.xml is not defined:{}",
param);
}
Dialect dialect = null;
switch (type) {
case SQLSERVER:
break;
case SQLSERVER2005:
dialect = new SQLServer2005Dialect();
break;
case SQLSERVER2008:
dialect = new SQLServer2008Dialect();
break;
case ORACLE9I:
break;
case ORACLE10G:
break;
case ORACLE11G:
break;
case MYSQL5:
break;
}
return dialect;
}
}
package com.eman.core.dialect;
/**
* sql2008数据库的实现
*
* @author liud
*
*/
public class SQLServer2008Dialect implements Dialect {
private static final String SELECT = "select";
private static final String FROM = "from";
private static final String DISTINCT = "distinct";
@Override
public String getTotalString(String sql) {
StringBuilder sb = new StringBuilder(sql.trim().toLowerCase());
int orderbyIndex = sb.indexOf("order by");
if (orderbyIndex != -1) {
sb.delete(orderbyIndex, sb.length());
}
sb.insert(0, "WITH query AS (").append(
") SELECT count(*) total FROM query ");
return sb.toString();
}
@Override
public String getLimitString(String sql, int offset, int limit) {
if (offset > 1 || limit > 1)
return getLimitString(sql, offset, limit, true);
return sql;
}
/**
* Add a LIMIT clause to the given SQL SELECT (HHH-2655: ROW_NUMBER for
* Paging)
*
* The LIMIT SQL will look like:
*
*
* WITH query AS (
* SELECT ROW_NUMBER() OVER (ORDER BY orderby) as __liud_row_nr__,
* original_query_without_orderby
* )
* SELECT * FROM query WHERE __liud_row_nr__ BEETWIN offset AND offset + last
*
*
*
* @param querySqlString
* The SQL statement to base the limit query off of.
* @param offset
* Offset of the first row to be returned by the query
* (zero-based)
* @param limit
* Maximum number of rows to be returned by the query
*
* @return A new SQL statement with the LIMIT clause applied.
*/
private String getLimitString(String querySqlString, int offset, int limit,
boolean hasOffset) {
StringBuilder sb = new StringBuilder(querySqlString.trim()
.toLowerCase());
int orderByIndex = sb.indexOf("order by");
CharSequence orderby = orderByIndex > 0 ? sb.subSequence(orderByIndex,
sb.length()) : "ORDER BY CURRENT_TIMESTAMP";
// Delete the order by clause at the end of the query
if (orderByIndex > 0) {
sb.delete(orderByIndex, orderByIndex + orderby.length());
}
// HHH-5715 bug fix
replaceDistinctWithGroupBy(sb);
insertRowNumberFunction(sb, orderby);
// Wrap the query within a with statement:
sb.insert(0, "WITH query AS (").append(") SELECT * FROM query ");
sb.append("WHERE __liud_row_nr__ BETWEEN ").append(offset + 1)
.append(" AND ").append(offset + limit);
return sb.toString();
}
/**
* Right after the select statement of a given query we must place the
* row_number function
*
* @param sql
* the initial sql query without the order by clause
* @param orderby
* the order by clause of the query
*/
protected static void insertRowNumberFunction(StringBuilder sql,
CharSequence orderby) {
// Find the end of the select statement
int selectEndIndex = sql.indexOf(SELECT) + SELECT.length();
// Insert after the select statement the row_number() function:
sql.insert(selectEndIndex, " ROW_NUMBER() OVER (" + orderby
+ ") as __liud_row_nr__,");
}
/**
* Utility method that checks if the given sql query is a select distinct
* one and if so replaces the distinct select with an equivalent simple
* select with a group by clause. See
* {@link SQLServer2005DialectTestCase#testReplaceDistinctWithGroupBy()}
*
* @param sql
* an sql query
*/
protected static void replaceDistinctWithGroupBy(StringBuilder sql) {
int distinctIndex = sql.indexOf(DISTINCT);
if (distinctIndex > 0) {
sql.delete(distinctIndex, distinctIndex + DISTINCT.length() + 1);
sql.append(" group by").append(getSelectFieldsWithoutAliases(sql));
}
}
/**
* This utility method searches the given sql query for the fields of the
* select statement and returns them without the aliases. See
* {@link SQLServer2005DialectTestCase#testGetSelectFieldsWithoutAliases()}
*
* @param an
* sql query
* @return the fields of the select statement without their alias
*/
protected static CharSequence getSelectFieldsWithoutAliases(
StringBuilder sql) {
String select = sql.substring(sql.indexOf(SELECT) + SELECT.length(),
sql.indexOf(FROM));
// Strip the as clauses
return stripAliases(select);
}
/**
* Utility method that strips the aliases. See
* {@link SQLServer2005DialectTestCase#testStripAliases()}
*
* @param a
* string to replace the as statements
* @return a string without the as statements
*/
protected static String stripAliases(String str) {
return str.replaceAll("\\sas[^,]+(,?)", "$1");
}
}
以上是集成了mybatis的分页功能,只需要调用第一方法即可以实现。实现方式采用了hibernate分页方式。
2013年6月09日 14:57
mysql ibatis 分页_MyBatis怎样实现MySQL动态分页?相关推荐
- mybatis mysql 模糊查询_MyBatis Oracle、MySQL、DB2、SQLServer的like模糊查询
Oracle数据库: select * from t_user where name like '%'||#{search_name}||'%' 或者 select * from t_user whe ...
- 基于SpringDataJpa的mysql动态分页多表查询
基于SpringDataJpa的mysql动态分页多表查询 由于这篇文章预计篇幅会很长,关于Spring Data JPA的知识就简短的分享,更多的请自行度娘,JPA 封装了很多查询的接口,但今天要讲 ...
- Mybatis+MySQL动态分页查询数据经典案例
最近在用Mybatis做项目的时候遇到了不少问题,今天我就在这和大家分享一下,稀稀拉拉的研究了两天,终于搞好了! 开发人员:1111 开发软件:Myeclipse 用到的框架技术:Mybatis 数据 ...
- Mybatis+MySQL动态分页查询数据经典案例(含代码以及测试)
最近在用Mybatis做项目的时候遇到了不少问题,今天我就在这和大家分享一下,稀稀拉拉的研究了两天,终于搞好了! 开发人员:1111 开发软件:Myeclipse 用到的框架技术:Mybatis 数据 ...
- jpa mysql sql分页查询语句_JPA多条件复杂SQL动态分页查询功能
概述 ORM映射为我们带来便利的同时,也失去了较大灵活性,如果SQL较复杂,要进行动态查询,那必定是一件头疼的事情(也可能是lz还没发现好的方法),记录下自己用的三种复杂查询方式. 环境 spring ...
- Mybatis+mysql动态分页查询数据案例——房屋信息的接口(IHouseDao)
package cn.bdqn.mhouse.dao;import java.util.List;import cn.bdqn.mhouse.entity.House; import cn.bdqn. ...
- mysql四剑客_MyBatis三剑客
MyBatis三剑客 MyBatis 可以通过 XML 或注解来配置和映射原始类型.接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录 ...
- mysql数据库千万级别数据的查询优化和分页测试
原文地址:原创 mysql数据库千万级别数据的查询优化和分页测试作者:于堡舰 本文为本人最近利用几个小时才分析总结出的原创文章,希望大家转载,但是要注明出处 http://blog.sina.co ...
- mysql分页查询出租房屋信息_分页查询信息(使用jdbc连接mysql数据库实现分页查询任务)...
分页查询信息 使用jdbc连接mysql数据库实现分页查询任务 通过mysql数据库提供的分页机制,实现商品信息的分页查询功能,将查询到的信息显示到jsp页面上. 本项目时一个简单的运用eclipse ...
最新文章
- 查看 Laravel 的 SQL 语句的方法
- 【STM32】FreeRTOS创建和删除任务示例(动态方法)
- mysql update 行迁移_Oracle行迁移和行链接详解
- 图片压缩上传Thumbnailator 插件
- ACM题解系列之一:刘汝佳:《算法竞赛入门经典》(第2版)
- 《Linux内核设计与实现》读书笔记(2)--- 进程管理
- ITester软件测试小栈,点击领取你的能量值!
- (转)菜鸟学数据库(二)——触发器
- 4x4矩阵键盘c语言,4X4键盘矩阵键盘程序
- 122 Best Time to Buy and Sell Stock II
- stm32的rxcallback再debug界面显示没有编译,uC/OS-III
- 安装centos 6.5
- 网关报错:Load balancer does not have available server for client: xxx
- 数据库的几种去重方法总结
- Matlab将底色改为白色
- Executor与线程池
- win10只能发现部分计算机,Win10的隐藏小秘密,被我发现了
- HTML-----第二章表格及样式
- linux查看etc下yam文件,在Linux上用Netplan进行网络配置
- 常用模块fractions基本使用