- 浏览: 485863 次
- 性别:
- 来自: 武汉
最新评论
-
zyzyzy123:
请问有工程吗,我现在正在实现打电话的功能,但是一直不通,怀疑是 ...
实用的java 串口通信程序 -
wuhaitong:
引用[img][/img][*][url][/url] ...
jbpm -
迷糊_le:
maven命令, 蛮好的,谢谢
maven eclipse -
Wuaner:
不错的文章 , 谢谢分享!
Hadoop -
yuqihengsheng:
strong 很细
HighLighter
iBatis默认的分页是采用游标滚动的方式来实现的,这种方式在大数据量的情况下便会OOM了,因此一般都采用手写分页SQL语句使用数据库物理分页方式实现,参考了网上很多网友所写的如何实现像hibernate一样使用方言的方式来实现分页功能,基本上千篇一律都是继承com.ibatis.sqlmap.engine.execution.SqlExecutor类然后在spring中进行注入等等,操作复杂编码甚多,方法不可取。
另外还有些是修改iBatis的jar包来实现,本人觉得这种方法更不可取。
基于网友们的思想,自己实现了另一种方法,不用修改源码,不用在spring中做任何配置即可实现物理分页功能:
条件
1、JVM类的加载是通过Class.forName(String cls)来实现,根据这个原理可以自己写一个与com.ibatis.sqlmap.engine.execution.SqlExecutor同名类;
2、java web类的加载顺序是:首先是web容器的相关类与jar包,然后是web工程下面WEB-INF/classes/下的所有类,最后才是WEB-INF/lib下的所有jar包;
有了以上的先决条件就好办了,可以在你的项目src目录下建包com.ibatis.sqlmap.engine.execution,然后在此包下建类SqlExecutor,然后把iBatis包下的这个类的源码复制进来后做小小改动,原来的executeQuery方法改成私有、换名,换成什么名称随便,然后新建一个公有的executeQuery方法,分页功能就在这个方法体内实现;
这样一来,web容器首会找到WEB-INF/classes下的com.ibatis.sqlmap.engine.execution.SqlExecutor这个类,因而会忽略掉在ibatis包中的这个类,即实现了自定义的分页功能,又不用去破坏ibatis的包;
还有一点,也可以将自定义的这个类打成jar包放到lib中去,不过这时就要注意了,jar包的名称一定要在ibatis包的名称之前,也就是说ibatis-2.3.4.726.jar,那么这个jar就可以写成ibatis-2.3.4.725.jar,或者字母在ibatis这几个字母之前,这样才能正确加载自己写的那个类。
贴上代码:
SqlExecutor.java
- /*
- * Copyright 2004 Clinton Begin
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package com.ibatis.sqlmap.engine.execution;
- import java.sql.BatchUpdateException;
- import java.sql.CallableStatement;
- import java.sql.Connection;
- import java.sql.PreparedStatement;
- import java.sql.ResultSet;
- import java.sql.SQLException;
- import java.sql.Statement;
- import java.sql.Types;
- import java.util.ArrayList;
- import java.util.List;
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
- import com.ibatis.sqlmap.engine.impl.SqlMapClientImpl;
- import com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate;
- import com.ibatis.sqlmap.engine.mapping.parameter.ParameterMap;
- import com.ibatis.sqlmap.engine.mapping.parameter.ParameterMapping;
- import com.ibatis.sqlmap.engine.mapping.result.ResultMap;
- import com.ibatis.sqlmap.engine.mapping.result.ResultObjectFactoryUtil;
- import com.ibatis.sqlmap.engine.mapping.statement.DefaultRowHandler;
- import com.ibatis.sqlmap.engine.mapping.statement.MappedStatement;
- import com.ibatis.sqlmap.engine.mapping.statement.RowHandlerCallback;
- import com.ibatis.sqlmap.engine.scope.ErrorContext;
- import com.ibatis.sqlmap.engine.scope.SessionScope;
- import com.ibatis.sqlmap.engine.scope.StatementScope;
- /**
- * Class responsible for executing the SQL
- */
- @SuppressWarnings ("unchecked")
- public class SqlExecutor {
- private static final Log log = LogFactory.getLog(SqlExecutor.class);
- //
- // Constants
- //
- /**
- * Constant to let us know not to skip anything
- */
- public static final int NO_SKIPPED_RESULTS = 0;
- /**
- * Constant to let us know to include all records
- */
- public static final int NO_MAXIMUM_RESULTS = -999999;
- public SqlExecutor() {
- log.info("Custom class 'SqlExecutor' Initialization");
- }
- //
- // Public Methods
- //
- /**
- * Execute an update
- *
- * @param statementScope
- * - the request scope
- * @param conn
- * - the database connection
- * @param sql
- * - the sql statement to execute
- * @param parameters
- * - the parameters for the sql statement
- * @return - the number of records changed
- * @throws SQLException
- * - if the update fails
- */
- public int executeUpdate(StatementScope statementScope, Connection conn,
- String sql, Object[] parameters) throws SQLException {
- ErrorContext errorContext = statementScope.getErrorContext();
- errorContext.setActivity("executing update");
- errorContext.setObjectId(sql);
- PreparedStatement ps = null;
- setupResultObjectFactory(statementScope);
- int rows = 0;
- try {
- errorContext
- .setMoreInfo("Check the SQL Statement (preparation failed).");
- ps = prepareStatement(statementScope.getSession(), conn, sql);
- setStatementTimeout(statementScope.getStatement(), ps);
- errorContext
- .setMoreInfo("Check the parameters (set parameters failed).");
- statementScope.getParameterMap().setParameters(statementScope, ps,
- parameters);
- errorContext.setMoreInfo("Check the statement (update failed).");
- ps.execute();
- rows = ps.getUpdateCount();
- } finally {
- closeStatement(statementScope.getSession(), ps);
- }
- return rows;
- }
- /**
- * Adds a statement to a batch
- *
- * @param statementScope
- * - the request scope
- * @param conn
- * - the database connection
- * @param sql
- * - the sql statement
- * @param parameters
- * - the parameters for the statement
- * @throws SQLException
- * - if the statement fails
- */
- public void addBatch(StatementScope statementScope, Connection conn,
- String sql, Object[] parameters) throws SQLException {
- Batch batch = (Batch) statementScope.getSession().getBatch();
- if (batch == null) {
- batch = new Batch();
- statementScope.getSession().setBatch(batch);
- }
- batch.addBatch(statementScope, conn, sql, parameters);
- }
- /**
- * Execute a batch of statements
- *
- * @param sessionScope
- * - the session scope
- * @return - the number of rows impacted by the batch
- * @throws SQLException
- * - if a statement fails
- */
- public int executeBatch(SessionScope sessionScope) throws SQLException {
- int rows = 0;
- Batch batch = (Batch) sessionScope.getBatch();
- if (batch != null) {
- try {
- rows = batch.executeBatch();
- } finally {
- batch.cleanupBatch(sessionScope);
- }
- }
- return rows;
- }
- /**
- * Execute a batch of statements
- *
- * @param sessionScope
- * - the session scope
- * @return - a List of BatchResult objects (may be null if no batch has been
- * initiated). There will be one BatchResult object in the list for
- * each sub-batch executed
- * @throws SQLException
- * if a database access error occurs, or the drive does not
- * support batch statements
- * @throws BatchException
- * if the driver throws BatchUpdateException
- */
- public List executeBatchDetailed(SessionScope sessionScope)
- throws SQLException, BatchException {
- List answer = null;
- Batch batch = (Batch) sessionScope.getBatch();
- if (batch != null) {
- try {
- answer = batch.executeBatchDetailed();
- } finally {
- batch.cleanupBatch(sessionScope);
- }
- }
- return answer;
- }
- /**
- * Long form of the method to execute a query
- *
- * @param statementScope
- * - the request scope
- * @param conn
- * - the database connection
- * @param sql
- * - the SQL statement to execute
- * @param parameters
- * - the parameters for the statement
- * @param skipResults
- * - the number of results to skip
- * @param maxResults
- * - the maximum number of results to return
- * @param callback
- * - the row handler for the query
- * @throws SQLException
- * - if the query fails
- */
- //------------------------------- 分页代码重写(start) ------------------------------------//
- //重写executeQuery方法,首先判断是否分页查询,分页查询先将分页SQL语句构建,然后执行iBatis默认的查询
- public void executeQuery(StatementScope statementScope, Connection conn,
- String sql, Object[] parameters, int skipResults, int maxResults,
- RowHandlerCallback callback) throws SQLException {
- //取数据库产品名称
- String dbName = conn.getMetaData().getDatabaseProductName();
- int len = sql.length();
- //判断是否分页
- if ((skipResults != NO_SKIPPED_RESULTS || maxResults != NO_MAXIMUM_RESULTS)) {
- //根据数据库产品名称取对应的分页SQL语句
- sql = Dialect.getLimitString(dbName, sql, skipResults, maxResults);
- //分页语句是否存在
- if (sql.length() != len) {
- skipResults = NO_SKIPPED_RESULTS;
- maxResults = NO_MAXIMUM_RESULTS;
- }
- }
- iBatisExecuteQuery(statementScope, conn, sql, parameters, skipResults,
- maxResults, callback);
- }
- //iBatis包中默认的executeQuery方法
- private void iBatisExecuteQuery(StatementScope statementScope,
- Connection conn, String sql, Object[] parameters, int skipResults,
- int maxResults, RowHandlerCallback callback) throws SQLException {
- ErrorContext errorContext = statementScope.getErrorContext();
- errorContext.setActivity("executing query");
- errorContext.setObjectId(sql);
- PreparedStatement ps = null;
- ResultSet rs = null;
- setupResultObjectFactory(statementScope);
- try {
- errorContext
- .setMoreInfo("Check the SQL Statement (preparation failed).");
- Integer rsType = statementScope.getStatement().getResultSetType();
- if (rsType != null) {
- ps = prepareStatement(statementScope.getSession(), conn, sql,
- rsType);
- } else {
- ps = prepareStatement(statementScope.getSession(), conn, sql);
- }
- setStatementTimeout(statementScope.getStatement(), ps);
- Integer fetchSize = statementScope.getStatement().getFetchSize();
- if (fetchSize != null) {
- ps.setFetchSize(fetchSize.intValue());
- }
- errorContext
- .setMoreInfo("Check the parameters (set parameters failed).");
- statementScope.getParameterMap().setParameters(statementScope, ps,
- parameters);
- errorContext.setMoreInfo("Check the statement (query failed).");
- ps.execute();
- errorContext
- .setMoreInfo("Check the results (failed to retrieve results).");
- // Begin ResultSet Handling
- rs = handleMultipleResults(ps, statementScope, skipResults,
- maxResults, callback);
- // End ResultSet Handling
- } finally {
- try {
- closeResultSet(rs);
- } finally {
- closeStatement(statementScope.getSession(), ps);
- }
- }
- }
- //-------------------- 分页代码重写(end) -------------------------------------//
- /**
- * Execute a stored procedure that updates data
- *
- * @param statementScope
- * - the request scope
- * @param conn
- * - the database connection
- * @param sql
- * - the SQL to call the procedure
- * @param parameters
- * - the parameters for the procedure
- * @return - the rows impacted by the procedure
- * @throws SQLException
- * - if the procedure fails
- */
- public int executeUpdateProcedure(StatementScope statementScope,
- Connection conn, String sql, Object[] parameters)
- throws SQLException {
- ErrorContext errorContext = statementScope.getErrorContext();
- errorContext.setActivity("executing update procedure");
- errorContext.setObjectId(sql);
- CallableStatement cs = null;
- setupResultObjectFactory(statementScope);
- int rows = 0;
- try {
- errorContext
- .setMoreInfo("Check the SQL Statement (preparation failed).");
- cs = prepareCall(statementScope.getSession(), conn, sql);
- setStatementTimeout(statementScope.getStatement(), cs);
- ParameterMap parameterMap = statementScope.getParameterMap();
- ParameterMapping[] mappings = parameterMap.getParameterMappings();
- errorContext
- .setMoreInfo("Check the output parameters (register output parameters failed).");
- registerOutputParameters(cs, mappings);
- errorContext
- .setMoreInfo("Check the parameters (set parameters failed).");
- parameterMap.setParameters(statementScope, cs, parameters);
- errorContext
- .setMoreInfo("Check the statement (update procedure failed).");
- cs.execute();
- rows = cs.getUpdateCount();
- errorContext
- .setMoreInfo("Check the output parameters (retrieval of output parameters failed).");
- retrieveOutputParameters(statementScope, cs, mappings, parameters,
- null);
- } finally {
- closeStatement(statementScope.getSession(), cs);
- }
- return rows;
- }
- /**
- * Execute a stored procedure
- *
- * @param statementScope
- * - the request scope
- * @param conn
- * - the database connection
- * @param sql
- * - the sql to call the procedure
- * @param parameters
- * - the parameters for the procedure
- * @param skipResults
- * - the number of results to skip
- * @param maxResults
- * - the maximum number of results to return
- * @param callback
- * - a row handler for processing the results
- * @throws SQLException
- * - if the procedure fails
- */
- public void executeQueryProcedure(StatementScope statementScope,
- Connection conn, String sql, Object[] parameters, int skipResults,
- int maxResults, RowHandlerCallback callback) throws SQLException {
- ErrorContext errorContext = statementScope.getErrorContext();
- errorContext.setActivity("executing query procedure");
- errorContext.setObjectId(sql);
- CallableStatement cs = null;
- ResultSet rs = null;
- setupResultObjectFactory(statementScope);
- try {
- errorContext
- .setMoreInfo("Check the SQL Statement (preparation failed).");
- Integer rsType = statementScope.getStatement().getResultSetType();
- if (rsType != null) {
- cs = prepareCall(statementScope.getSession(), conn, sql, rsType);
- } else {
- cs = prepareCall(statementScope.getSession(), conn, sql);
- }
- setStatementTimeout(statementScope.getStatement(), cs);
- Integer fetchSize = statementScope.getStatement().getFetchSize();
- if (fetchSize != null) {
- cs.setFetchSize(fetchSize.intValue());
- }
- ParameterMap parameterMap = statementScope.getParameterMap();
- ParameterMapping[] mappings = parameterMap.getParameterMappings();
- errorContext
- .setMoreInfo("Check the output parameters (register output parameters failed).");
- registerOutputParameters(cs, mappings);
- errorContext
- .setMoreInfo("Check the parameters (set parameters failed).");
- parameterMap.setParameters(statementScope, cs, parameters);
- errorContext
- .setMoreInfo("Check the statement (update procedure failed).");
- cs.execute();
- errorContext
- .setMoreInfo("Check the results (failed to retrieve results).");
- // Begin ResultSet Handling
- rs = handleMultipleResults(cs, statementScope, skipResults,
- maxResults, callback);
- // End ResultSet Handling
- errorContext
- .setMoreInfo("Check the output parameters (retrieval of output parameters failed).");
- retrieveOutputParameters(statementScope, cs, mappings, parameters,
- callback);
- } finally {
- try {
- closeResultSet(rs);
- } finally {
- closeStatement(statementScope.getSession(), cs);
- }
- }
- }
- private ResultSet handleMultipleResults(PreparedStatement ps,
- StatementScope statementScope, int skipResults, int maxResults,
- RowHandlerCallback callback) throws SQLException {
- ResultSet rs;
- rs = getFirstResultSet(statementScope, ps);
- if (rs != null) {
- handleResults(statementScope, rs, skipResults, maxResults, callback);
- }
- // Multiple ResultSet handling
- if (callback.getRowHandler() instanceof DefaultRowHandler) {
- MappedStatement statement = statementScope.getStatement();
- DefaultRowHandler defaultRowHandler = ((DefaultRowHandler) callback
- .getRowHandler());
- if (statement.hasMultipleResultMaps()) {
- List multipleResults = new ArrayList();
- multipleResults.add(defaultRowHandler.getList());
- ResultMap[] resultMaps = statement.getAdditionalResultMaps();
- int i = 0;
- while (moveToNextResultsSafely(statementScope, ps)) {
- if (i >= resultMaps.length)
- break;
- ResultMap rm = resultMaps[i];
- statementScope.setResultMap(rm);
- rs = ps.getResultSet();
- DefaultRowHandler rh = new DefaultRowHandler();
- handleResults(statementScope, rs, skipResults, maxResults,
- new RowHandlerCallback(rm, null, rh));
- multipleResults.add(rh.getList());
- i++;
- }
- defaultRowHandler.setList(multipleResults);
- statementScope.setResultMap(statement.getResultMap());
- } else {
- while (moveToNextResultsSafely(statementScope, ps))
- ;
- }
- }
- // End additional ResultSet handling
- return rs;
- }
- private ResultSet getFirstResultSet(StatementScope scope, Statement stmt)
- throws SQLException {
- ResultSet rs = null;
- boolean hasMoreResults = true;
- while (hasMoreResults) {
- rs = stmt.getResultSet();
- if (rs != null) {
- break;
-
发表评论
-
安装和使用memcached
2014-04-16 16:24 644如何将 memcached 融入到 ... -
applicationContext.xml
2013-08-09 09:05 948<?xml version="1.0&quo ... -
注释驱动的 Spring cache 缓存介绍
2013-08-08 07:04 665概述 Spring 3.1 引入了激动人心的基于注释(an ... -
Spring2.5 Annotations
2013-08-08 06:33 862完成setXxxx功能,即配置文件的 <propert ... -
Spring基于注解的缓存配置--EHCache AND OSCache
2013-08-07 23:21 1032本文将构建一个普通工程来说明spring注解缓存的使用方式, ... -
Ehcache 整合Spring 使用页面、对象缓存
2013-08-07 22:51 899Ehcache 整合Spring 使用页面、对象缓存 ... -
javassist教程和示例
2013-05-18 08:57 2014Javassist是一个执行字节 ... -
ZooKeeper官方文档
2013-05-16 17:09 1563介绍(源自ZooKeeper官方文档) 学习HBase过程 ... -
ZooKeeper -例子
2013-05-16 17:08 1217ZooKeeper ZooKeepe ... -
Spring整合Hessian访问远程服务
2013-05-15 13:44 860Spring整合Hessian访问远程服务 目录 1.1 ... -
redis
2013-05-14 11:44 773redis是一个key-value存储系统。和Memcach ... -
spring 资源访问
2013-05-13 08:26 1003spring在java基础上封装了资源访问,简单易用。 R ... -
ZooKeeper——入门
2013-05-08 16:12 913ZooKeeper——入门 博客分类: ZooK ... -
分布式服务框架 Zookeeper -- 管理分布式环境中的数据(IBM)
2013-05-08 14:07 788安装和配置详解 本文 ... -
分布式协调服务---Zookeeper
2013-05-08 14:05 7791、Zookeeper overview Zookee ... -
Hibernate
2013-03-28 13:04 927一、简述 Hibernate 和 JD ... -
Apache+Tomcat集群配置详解
2013-02-01 10:52 898Apache + Tomcat集群配置详解(1) 一、 ... -
Apache+Jboss集群基于反向代理的负载均衡
2013-02-01 10:40 2498假设三台机器IP分别为172.29.128.100、172. ... -
spring + ibatis 多数据源事务(分布式事务)管理配置方法
2012-12-17 15:18 1270spring + ibatis 多数据源事务(分布式事务 ... -
Hessian序列化不设SerializerFactory性能问题
2012-10-31 09:47 1504Hessian序列化不设SerializerFactor ...
相关推荐
标题中的“ibatis分页”指的是在使用iBATIS(一个SQL映射框架)时,如何实现数据库查询结果的分页显示。iBATIS通过XML配置文件或注解方式将Java代码与SQL语句分离,提供了更灵活的数据库操作方式。在处理大量数据时...
标题"ibatis分页功能"指的就是如何在iBATIS框架中实现数据库查询的分页效果。分页不仅提高了用户体验,还能减少不必要的数据库负载。 描述中提到,分页功能是通过`page.tld`标签实现的。`tld`文件是JSP Tag Library...
本文将深入探讨Ibatis实现分页的相关知识点,并基于提供的标签“源码”和“工具”,分享如何在实际项目中运用Ibatis进行分页处理。 首先,了解Ibatis的基本概念。Ibatis是由Apache基金会维护的一个开源项目,它是一...
iBatis分页源代码解析.chm,ibatis介绍等
本知识点将深入探讨如何在Struts2框架中结合iBatis实现基于Freemarker模板的分页功能。 首先,我们需要理解iBatis,它是一个轻量级的Java持久层框架,它提供了一个SQL映射框架,允许开发者将SQL语句与Java代码分离...
公司的大部分项目都开始使用IBatis作为O/R Mapping了,但是在使用的过程中也发现了很多不方便和存在争议的地方,其中一个不方便的地方就是分页,目前的处理方式都是在sqlMap中写针对特定数据库的物理分页Sql语句,对于...
### ibatis分页技术详解与应用 在软件开发领域,特别是在数据库操作中,分页是一项极为常见的需求。分页不仅可以优化用户体验,减少加载时间,还能有效地管理大量的数据查询结果。Ibatis,作为一款优秀的持久层框架...
本篇文章将深入探讨如何在Xwork和iBatis的集成应用中实现分页功能,让开发者能够更高效地处理大量数据。 首先,让我们了解什么是分页。分页是网页显示大量数据时常用的一种技术,它将结果集分割成若干小部分(页)...
在传统的iBatis框架中,分页通常采用逻辑分页的方式,即通过游标(ResultSet)来逐条处理数据,从而实现分页效果。这种方式虽然跨数据库兼容性好,但性能上不如数据库原生的物理分页高效。物理分页是直接在SQL语句中...
三、Ibatis分页实现 1. SQL配置 在Ibatis的Mapper XML文件中,我们需要编写一个带有参数的SQL查询,这些参数通常包括当前页码和每页记录数。例如: ```xml SELECT * FROM your_table != null and pageSize != ...
本项目基于ibatis框架实现了分页功能,覆盖了从底层数据库操作到页面展示的完整流程,包括DAO层、Service层、Action层以及JSP页面的展示。 首先,我们来了解一下什么是ibatis。Ibatis是一个优秀的持久层框架,它...
ibatis_likehbm高效分页组件ibatis_likehbm高效分页组件ibatis_likehbm高效分页组件ibatis_likehbm高效分页组件ibatis_likehbm高效分页组件ibatis_likehbm高效分页组件 ibatis_likehbm高效分页组件 ibatis_likehbm...
在2.3.4这个版本中,Ibatis 提供了数据库无关的分页功能,这是一种在不依赖特定数据库语法的情况下实现分页查询的方法,有助于提高代码的可移植性和维护性。 数据库无关分页的核心思想是将分页参数(如当前页数和每...
NULL 博文链接:https://jsufly.iteye.com/blog/508249
你可以定义一个Mapper接口和XML配置文件,编写SQL查询来获取指定页码的数据,并通过iBatis的参数映射功能传入分页参数。 文件列表中的`.classpath`和`.project`是Eclipse或类似的IDE的项目配置文件,它们定义了项目...
本项目"ibatis_with_memcached"就是关于如何将Ibatis与Memcached集成,实现高效的数据库缓存策略的实例。 Ibatis是一个基于Java的SQL映射框架,它允许开发者编写SQL语句并与Java对象进行绑定,从而避免了传统的JDBC...
ibatis 物理分页jar ,与官方ibatis不冲突,可直接使用。
"iBatis分页"是数据库操作中常见的需求,iBatis提供了方便的分页支持。在学习这部分时,你会了解如何在SQL中添加分页条件,以及如何在Java代码中处理分页结果。 "spring+iBatis处理1对多数据表实例"展示了如何将...
Ibatis.NET提供了分页查询的实现,下面我们将深入探讨如何在Ibatis.NET中实现分页。 首先,理解分页的基本概念。分页通常涉及两个关键参数:当前页码(Page Number)和每页记录数(PageSize)。例如,如果当前页码...
Ibatis SQLServerDialect 2008 分页 可实现SQLServerDialect 分页 支持ibatis3