`
atshow01
  • 浏览: 8412 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

MyBatis分页,自动总行数统计及Object[]数据结果(不修改源码)

阅读更多

 

 

原文查看http://www.cnblogs.com/jcli/archive/2011/08/09/2132222.html

将PaginationInterceptor稍作改进如下:

 

 

 

package com.sxf.mybatis.page;

import java.sql.Connection;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.ParameterMapping;
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.hibernate.dialect.Dialect;
import org.hibernate.dialect.MySQL5Dialect;

/**
 * MyBatis根据dialect分页(需要hibernate支持):数据库分页
 * 
 * @author 
 * 
 */
@Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class }) })
public class PaginationInterceptor implements Interceptor {

	private final static Log log = LogFactory
			.getLog(PaginationInterceptor.class);

	@Override
	public Object intercept(Invocation invocation) throws Throwable {
		StatementHandler statementHandler = (StatementHandler) invocation
				.getTarget();
		BoundSql boundSql = statementHandler.getBoundSql();
		MetaObject metaStatementHandler = MetaObject
				.forObject(statementHandler);
		RowBounds rowBounds = (RowBounds) metaStatementHandler
				.getValue("delegate.rowBounds");
		if (rowBounds == null || rowBounds == RowBounds.DEFAULT) {
			return invocation.proceed();
		}
		Configuration configuration = (Configuration) metaStatementHandler
				.getValue("delegate.configuration");
		String databaseType = null;
		try {
			databaseType = configuration.getVariables().getProperty("dialect")
					.toUpperCase();
		} catch (Exception e) {
			// ignore
		}

		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;
		if ("MySQL".equalsIgnoreCase(databaseType)) {
			dialect = new MySQL5Dialect();
		} else if ("MySQL5InnoDB".equalsIgnoreCase(databaseType)) {
			dialect = new MySQL5InnoDBDialect();
		} else if ("MySQLMyISAM".equalsIgnoreCase(databaseType)) {
			dialect = new MySQLMyISAMDialect();
		} else if ("ORACLE9I".equalsIgnoreCase(databaseType)) {
			dialect = new Oracle9iDialect();
		} else if ("ORACLE10g".equalsIgnoreCase(databaseType)) {
			dialect = new Oracle10gDialect();
		} else if ("SqlServer2005".equalsIgnoreCase(databaseType)) {
			dialect = new SQLServer2005Dialect();
		} else if ("SqlServer2008".equalsIgnoreCase(databaseType)) {
			dialect = new SQLServer2008Dialect();
		} else if ("SqlServer".equalsIgnoreCase(databaseType)) {
			dialect = new SQLServerDialect();
		}

		if (rowBounds.getLimit() > 0
				&& rowBounds.getLimit() < RowBounds.NO_ROW_LIMIT) {

			String originalSql = (String) metaStatementHandler
					.getValue("delegate.boundSql.sql");

			String desSql = dialect.getLimitString(originalSql,
					rowBounds.getOffset(), rowBounds.getLimit());

			metaStatementHandler.setValue("delegate.boundSql.sql", desSql);

			String addSql = desSql.replace(originalSql, "");

			Pattern pattern = Pattern.compile("[?]");
			Matcher matcher = pattern.matcher(addSql);
			int size = 0;
			while (matcher.find()) {
				size++;
			}

			if (size == 1) {
				ParameterMapping.Builder builder = new ParameterMapping.Builder(
						configuration, "limit", Integer.class);
				boundSql.getParameterMappings().add(builder.build());
				boundSql.setAdditionalParameter("limit", rowBounds.getLimit());
			}
			if (size == 2) {

				ParameterMapping.Builder builder = new ParameterMapping.Builder(
						configuration, "offset", Integer.class);
				boundSql.getParameterMappings().add(builder.build());
				boundSql.setAdditionalParameter("offset", rowBounds.getOffset());

				builder = new ParameterMapping.Builder(configuration, "limit",
						Integer.class);
				boundSql.getParameterMappings().add(builder.build());
				boundSql.setAdditionalParameter("limit", rowBounds.getLimit());
			}

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

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

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

	}

	@Override
	public void setProperties(Properties properties) {

	}

}

 此处分页需要Hibernate的jar包的dialect支持.

 

分享到:
评论

相关推荐

    mybatis分页源码

    在实际项目开发中,分页查询是必不可少的需求,MyBatis 提供了多种分页方式,如基于 RowBounds 的简单分页、基于 PageHelper 插件的高效分页等。本文将深入探讨 MyBatis 分页源码,了解其内部实现机制。 ### ...

    mybatis逻辑分页,含分页导航

    在提供的`pagination-demo`压缩包中,可能包含了一个完整的MyBatis分页示例,包括了XML映射文件、Java代码以及如何在前端展示分页导航的示例。通过研究这个示例,可以更直观地理解和掌握MyBatis的分页技巧。

    mybatis3.x源码深度解析与最佳实践.pdf

    MyBatis 3.x 源码深度解析与最佳实践 MyBatis 是当前最流行的 Java 持久层框架之一,其通过 XML 配置的方式消除了绝大部分 JDBC 重复代码以及参数的设置,结果集的映射。为了更好地学习和理解 MyBatis 背后的设计...

    Mybatis分页插件使用方法详解

    Mybatis分页插件使用方法详解 Mybatis分页插件是一款功能强大且广泛使用的插件,主要用于实现Mybatis框架下的分页查询。下面将详细介绍Mybatis分页插件的使用方法,涵盖插件简介、插件使用、配置和代码实现等方面。...

    myBatis系列之八:分页查询

    PageHelper插件的工作原理是在SQL执行前动态修改SQL,插入分页关键字,然后通过ResultHandler处理结果集,将数据封装成分页对象。 4. **工具辅助**: 在实际开发中,除了源码阅读,还可以借助IDEA等工具进行快速...

    mybatis源码+练习代码+插件+log4j2+maven

    - 源码分析可以帮助理解MyBatis如何处理SQL映射、参数绑定、结果映射等核心机制,以及动态SQL的实现。 - `Executor`执行器是MyBatis的核心,它负责执行SQL,有SimpleExecutor、ReuseExecutor和BatchExecutor三种...

    springmybatis

    mybatis实战教程mybatis in action之七实现mybatis分页源码下载 mybatis实战教程mybatis in action之八mybatis 动态sql语句 mybatis实战教程mybatis in action之九mybatis 代码生成工具的使用 mybatis ...

    mybatis-generator-core-1.3.2

    Mybatis-Generator是一款强大的自动化工具,它可以帮助Java开发者自动生成Mybatis框架下的Mapper接口、实体类(Model)以及对应的XML映射文件。这个工具的主要目标是提高开发效率,减少重复劳动,让开发者能够将更多...

    Mybatis整合通用Dao,Mybatis整合通用Mapper,MyBatis3.x整合通用 Mapper3.5.x

    本文将深入探讨如何将MyBatis与通用Dao(Data Access Object)和通用Mapper进行整合,以提高开发效率和代码复用性。我们将以"Mybatis整合通用Dao,Mybatis整合通用Mapper,MyBatis3.x整合通用Mapper3.5.x"为主题,...

    Mybatis教程整理.pdf

    - **分页实现**:MyBatis提供了实现分页查询的方法,可以有效地处理大量数据的分页问题。 - **动态SQL**:MyBatis支持动态SQL,可以在运行时根据不同条件生成不同的SQL语句。 - **代码生成工具**:MyBatis提供了代码...

    Mybatis源码(4)-拦截器.pdf

    通过这种方式,Mybatis的拦截器机制可以深入到数据访问的各个层次,为开发者提供了极大的灵活性,使得在不修改源代码的情况下,能够对Mybatis的行为进行扩展和定制。开发者可以根据实际需求,创建自己的拦截器,例如...

    SpringMVC精品资源--Spring+SpringMVC+Mybatis+Maven+Mysql框架搭建与分页实例.zip

    在本资源包中,"SpringMVC精品资源--Spring+SpringMVC+Mybatis+Maven+Mysql框架搭建与分页实例.zip" 涵盖了五个关键的Java开发技术,它们是Spring、SpringMVC、Mybatis、Maven以及Mysql。这五个组件构成了一个完整的...

    springboot mybatis mapper.xml 配置

    本示例将深入探讨如何配置`mapper.xml`,并提供新增、修改、删除、查询及分页查询的实践案例,同时展示如何通过网页接口访问这些功能。 首先,确保在`pom.xml`中添加了Spring Boot和MyBatis的依赖。Spring Boot简化...

    纯sql分页源码java版

    在IT行业中,数据库分页是常见的需求,尤其是在处理大量数据时,为了提高用户体验和系统性能,通常会采用分页方式来展示数据。本资源提供的"纯sql分页源码java版"聚焦于如何在Java中利用SQL语句实现分页查询,支持...

    java逻辑分页

    在Java编程中,逻辑分页是一种常见的数据处理技术,特别是在Web应用中,用于展示大量数据时,以提高用户体验和性能。逻辑分页不同于物理分页,物理分页是在数据库层面进行数据切片,而逻辑分页则是在应用程序层面上...

    javaEEdao有分页、增、删、改、查及图案片上传显示图片源码

    本资源“javaEEdao有分页、增、删、改、查及图案片上传显示图片源码”是一个典型的JavaEE DAO(Data Access Object)实现,包含了Web开发中的核心功能模块,对于初学者来说是宝贵的实践材料。 1. **分页**:在大型...

    mybatis逆向工程

    MyBatis逆向工程是数据库表到Java代码的自动化生成工具,它极大地简化了开发过程,尤其是处理大量的数据表时。通过逆向工程,开发者可以快速地为每个表创建对应的Mapper接口、Mapper XML配置文件以及POJO(Plain Old...

    JAVA_JDBC面向对象分页(初步设计二之oracle)

    在处理大量数据时,分页查询是一种有效的策略,可以提高应用程序的性能,避免一次性加载过多数据导致内存压力。Oracle数据库作为一款广泛使用的商业数据库系统,经常在企业级应用中被采用。本篇文章将重点讨论如何...

    jsp+servlet分页

    分页的基本原理是通过计算总记录数和每页显示的记录数,确定页码,然后根据页码和每页大小从数据库中查询对应的数据。 **三、JSP实现分页** 在JSP中,通常使用EL(Expression Language)和JSTL(JavaServer Pages ...

Global site tag (gtag.js) - Google Analytics