`
gongsy
  • 浏览: 105053 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

改进ibatis 2.3支持物理分页

    博客分类:
  • java
阅读更多

支持物理分页
ibatis版本是2.3.4
下面贴的是在这个包里的接口及实现类~~~一共7个~

ICountRecords.java

package com.sys.addin.dao;

public interface ICountRecords {
public long getObjectTotal(String selectQuery, Object parameterObject);
public long getObjectTotal(String selectQuery);
}


BaseDaoiBatis.java

package com.sys.addin.dao;
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;

import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapException;
import com.ibatis.sqlmap.engine.execution.SqlExecutor;
import com.ibatis.sqlmap.engine.impl.ExtendedSqlMapClient;
import com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate;
public abstract class BaseDaoiBatis extends SqlMapClientDaoSupport implements ICountRecords{
private SqlExecutor sqlExecutor; 

public SqlExecutor getSqlExecutor() { 
return sqlExecutor; 


public void setSqlExecutor(SqlExecutor sqlExecutor) { 
this.sqlExecutor = sqlExecutor; 


public void setEnableLimit(boolean enableLimit) { 
if (sqlExecutor instanceof LimitSqlExecutor) { 
((LimitSqlExecutor) sqlExecutor).setEnableLimit(enableLimit); 



public void initialize() throws Exception { 
if (sqlExecutor != null) { 
SqlMapClient sqlMapClient = getSqlMapClientTemplate() 
.getSqlMapClient(); 
if (sqlMapClient instanceof ExtendedSqlMapClient) { 
ReflectUtil.setFieldValue(((ExtendedSqlMapClient) sqlMapClient) 
.getDelegate(), "sqlExecutor", SqlExecutor.class, 
sqlExecutor); 

}
}


public long getObjectTotal(String selectQuery, Object parameterObject) {
prepareCountQuery(selectQuery);
return (Long) getSqlMapClientTemplate().queryForObject(
CountStatementUtil.getCountStatementId(selectQuery),parameterObject);
}
public long getObjectTotal(String selectQuery) {
prepareCountQuery(selectQuery);
return (Long) getSqlMapClientTemplate().queryForObject(
CountStatementUtil.getCountStatementId(selectQuery));
}

protected void prepareCountQuery(String selectQuery) {
String countQuery = CountStatementUtil.getCountStatementId(selectQuery);
if (logger.isDebugEnabled()) {
logger.debug("Convert " + selectQuery + " to " + countQuery);
}
SqlMapClient sqlMapClient = getSqlMapClientTemplate().getSqlMapClient();
if (sqlMapClient instanceof ExtendedSqlMapClient) {
SqlMapExecutorDelegate delegate = ((ExtendedSqlMapClient) sqlMapClient) .getDelegate();
try {
delegate.getMappedStatement(countQuery);
}
catch (SqlMapException e) {
delegate.addMappedStatement(CountStatementUtil
.createCountStatement(delegate
.getMappedStatement(selectQuery)));
}

}
}

}


LimitSqlExecutor.java

package com.sys.addin.dao;
import java.sql.Connection; 
import java.sql.SQLException; 

import org.apache.commons.logging.Log; 
import org.apache.commons.logging.LogFactory; 


import com.ibatis.sqlmap.engine.execution.SqlExecutor; 
import com.ibatis.sqlmap.engine.mapping.statement.RowHandlerCallback; 
import com.ibatis.sqlmap.engine.scope.StatementScope;
import com.ibatis.sqlmap.engine.scope.StatementScope;
public class LimitSqlExecutor extends SqlExecutor{
private static final Log logger = LogFactory.getLog(LimitSqlExecutor.class); 

private Dialect dialect; 

private boolean enableLimit = true; 

public Dialect getDialect() { 
return dialect; 


public void setDialect(Dialect dialect) { 
this.dialect = dialect; 


public boolean isEnableLimit() { 
return enableLimit; 


public void setEnableLimit(boolean enableLimit) { 
this.enableLimit = enableLimit; 


@Override 
public void executeQuery(StatementScope statementScope, Connection conn, String sql, 
Object[] parameters, int skipResults, int maxResults, 
RowHandlerCallback callback) throws SQLException { 
if ((skipResults != NO_SKIPPED_RESULTS || maxResults != NO_MAXIMUM_RESULTS) 
&& supportsLimit()) { 
sql = dialect.getLimitString(sql, skipResults, maxResults); 
if(logger.isDebugEnabled()){ 
logger.debug(sql); 

skipResults = NO_SKIPPED_RESULTS; 
maxResults = NO_MAXIMUM_RESULTS;             

super.executeQuery(statementScope, conn, sql, parameters, skipResults, 
maxResults, callback); 


public boolean supportsLimit() { 
if (enableLimit && dialect != null) { 
return dialect.supportsLimit(); 

return false; 

}

Dialect.java

package com.sys.addin.dao;

public interface Dialect {
public boolean supportsLimit(); 

public String getLimitString(String sql, boolean hasOffset); 

public String getLimitString(String sql, int offset, int limit);
}


MySQLDialect.java

package com.sys.addin.dao;

public class MySQLDialect implements Dialect {

protected static final String SQL_END_DELIMITER = ";"; 

public String getLimitString(String sql, boolean hasOffset) { 
return new StringBuffer(sql.length() + 20).append(trim(sql)).append( 
hasOffset ? " limit ?,?" : " limit ?") 
.append(SQL_END_DELIMITER).toString(); 


public String getLimitString(String sql, int offset, int limit) {
/* oracle
sql = trim(sql); 
StringBuffer sb = new StringBuffer(sql.length() + 20);      
sb.append("select * from ( select sq.*, rownum as rn from ("); 
sb.append(this.trim(sql)); 
sb.append(") sq)row_limit where row_limit.rn between "); 
sb.append(limit * (offset-1) + 1); 
sb.append(" and ");
sb.append(limit * offset); 
* */
// offset 第几页    limit   每页个数   

sql = trim(sql); 
StringBuffer sb = new StringBuffer(sql.length() + 20); 
sb.append(sql); 
if (offset > 0) { 
sb.append(" limit ").append((offset-1)*limit).append(',').append(limit) 
.append(SQL_END_DELIMITER); 
} else { 
sb.append(" limit ").append(limit).append(SQL_END_DELIMITER); 
}
return sb.toString(); 


public boolean supportsLimit() { 
return true; 


private String trim(String sql) { 
sql = sql.trim(); 
if (sql.endsWith(SQL_END_DELIMITER)) { 
sql = sql.substring(0, sql.length() - 1 
- SQL_END_DELIMITER.length()); 

return sql; 


}

ReflectUtil.java

package com.sys.addin.dao;
import java.lang.reflect.Field; 
import java.lang.reflect.Method; 
import java.lang.reflect.Modifier; 

import org.apache.commons.logging.Log; 
import org.apache.commons.logging.LogFactory;
public class ReflectUtil {
private static final Log logger = LogFactory.getLog(ReflectUtil.class); 

public static void setFieldValue(Object target, String fname, Class ftype, 
Object fvalue) { 
if (target == null 
|| fname == null 
|| "".equals(fname) 
|| (fvalue != null && !ftype.isAssignableFrom(fvalue.getClass()))) { 
return; 

Class clazz = target.getClass(); 
try { 
Method method = clazz.getDeclaredMethod("set" 
+ Character.toUpperCase(fname.charAt(0)) 
+ fname.substring(1), ftype); 
if (!Modifier.isPublic(method.getModifiers())) { 
method.setAccessible(true); 

method.invoke(target, fvalue); 

} catch (Exception me) { 
if (logger.isDebugEnabled()) { 
logger.debug(me); 

try { 
Field field = clazz.getDeclaredField(fname); 
if (!Modifier.isPublic(field.getModifiers())) { 
field.setAccessible(true); 

field.set(target, fvalue); 
} catch (Exception fe) { 
if (logger.isDebugEnabled()) { 
logger.debug(fe); 





public static Object getFieldValue(Object target, String fname) { 
Object reslut = null;
if (target == null 
|| fname == null 
|| "".equals(fname)) { 
return null; 

Class clazz = target.getClass(); 
try { 
Field field = clazz.getDeclaredField(fname);
reslut =  field.get(fname);


} catch (Exception me) { 
if (logger.isDebugEnabled()) { 
logger.debug(me); 


return reslut;


}



CountStatementUtil.java

package com.sys.addin.dao;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

import com.sys.addin.dao.ReflectUtil;
import com.ibatis.common.jdbc.exception.NestedSQLException;
import com.ibatis.sqlmap.client.event.RowHandler;
import com.ibatis.sqlmap.engine.impl.ExtendedSqlMapClient;
import com.ibatis.sqlmap.engine.mapping.parameter.ParameterMap;
import com.ibatis.sqlmap.engine.mapping.result.AutoResultMap;
import com.ibatis.sqlmap.engine.mapping.result.ResultMapping;
import com.ibatis.sqlmap.engine.mapping.result.ResultMap;
import com.ibatis.sqlmap.engine.mapping.sql.Sql;
import com.ibatis.sqlmap.engine.mapping.statement.ExecuteListener;
import com.ibatis.sqlmap.engine.mapping.statement.MappedStatement;
import com.ibatis.sqlmap.engine.mapping.statement.RowHandlerCallback;
import com.ibatis.sqlmap.engine.mapping.statement.SelectStatement;
import com.ibatis.sqlmap.engine.scope.ErrorContext;
import com.ibatis.sqlmap.engine.scope.StatementScope;

public class CountStatementUtil {
public static MappedStatement createCountStatement(MappedStatement selectStatement) {
return new CountStatement((SelectStatement) selectStatement);
}

public static String getCountStatementId(String selectStatementId) {
return "__" + selectStatementId + "Count__";
}

}

class CountStatement extends SelectStatement {

public CountStatement(SelectStatement selectStatement) {
super();
setId(CountStatementUtil.getCountStatementId(selectStatement .getId()));
setResultSetType(selectStatement.getResultSetType());
setFetchSize(1);
setParameterMap(selectStatement.getParameterMap());
setParameterClass(selectStatement.getParameterClass());
setSql(selectStatement.getSql());
setSqlMapClient(selectStatement.getSqlMapClient());
setTimeout(selectStatement.getTimeout());
setResource(selectStatement.getResource());

List executeListeners = (List) ReflectUtil.getFieldValue(
selectStatement, "executeListeners");
if (executeListeners != null) {
for (Object listener : executeListeners) {
addExecuteListener((ExecuteListener) listener);
}
}


ResultMap resultMap = new AutoResultMap(
((ExtendedSqlMapClient) getSqlMapClient()).getDelegate(), false);
resultMap.setId(getId() + "-AutoResultMap");
resultMap.setResultClass(Long.class);
resultMap.setResource(getResource());
setResultMap(resultMap);
}

protected void executeQueryWithCallback(StatementScope request,
Connection conn, Object parameterObject, Object resultObject,
RowHandler rowHandler, int skipResults, int maxResults)
throws SQLException {
ErrorContext errorContext = request.getErrorContext();
errorContext
.setActivity("preparing the mapped statement for execution");
errorContext.setObjectId(this.getId());
errorContext.setResource(this.getResource());

try {
parameterObject = validateParameter(parameterObject);

Sql sql = getSql();

errorContext.setMoreInfo("Check the parameter map.");
ParameterMap parameterMap = sql.getParameterMap(request,
parameterObject);

errorContext.setMoreInfo("Check the result map.");
ResultMap resultMap = getResultMap(request, parameterObject, sql);

request.setResultMap(resultMap);
request.setParameterMap(parameterMap);

errorContext.setMoreInfo("Check the parameter map.");
Object[] parameters = parameterMap.getParameterObjectValues(
request, parameterObject);

errorContext.setMoreInfo("Check the SQL statement.");
String sqlString = getSqlString(request, parameterObject, sql);

errorContext.setActivity("executing mapped statement");
errorContext
.setMoreInfo("Check the SQL statement or the result map.");
RowHandlerCallback callback = new RowHandlerCallback(resultMap,
resultObject, rowHandler);
sqlExecuteQuery(request, conn, sqlString, parameters, skipResults,
maxResults, callback);

errorContext.setMoreInfo("Check the output parameters.");
if (parameterObject != null) {
postProcessParameterObject(request, parameterObject, parameters);
}

errorContext.reset();
sql.cleanup(request);
notifyListeners();
}
catch (SQLException e) {
errorContext.setCause(e);
throw new NestedSQLException(errorContext.toString(), e
.getSQLState(), e.getErrorCode(), e);
}
catch (Exception e) {
errorContext.setCause(e);
throw new NestedSQLException(errorContext.toString(), e);
}
}

private String getSqlString(StatementScope request, Object parameterObject, Sql sql) {
String sqlString = sql.getSql(request, parameterObject);

System.out.print("动态SQL :"+ request.getDynamicSql());

int start = sqlString.toLowerCase().indexOf("from");
if (start >= 0) {
sqlString = "SELECT COUNT(*) AS c " + sqlString.substring(start);
}
return sqlString;
}

private ResultMap getResultMap(StatementScope request,
Object parameterObject, Sql sql) {
return getResultMap();
}
}

然后是修改spring滴配置文件~~~~

applicationContext.xml

<!-- 为物理分页添加的bean -->
<!-- for mySql -->
<bean id="sqlExecutor" class="com.sys.addin.dao.LimitSqlExecutor">
<property name="dialect">
<bean class="com.sys.addin.dao.MySQLDialect" />
</property>
</bean>

<bean id="baseDao" abstract="true" class="com.sys.addin.dao.BaseDaoiBatis" init-method="initialize">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="sqlMapClient">
<ref bean="sqlMapClient" />
</property>
<property name="sqlExecutor">
<ref bean="sqlExecutor" />
</property>  
</bean> 
<!-- 为物理分页添加的bean结束 -->
<bean id="xxDAO" class="com.xx.dao.xxDaoImpl" parent="baseDao" ></bean>



使用的时候
Dao接口继承ICountRecords
在Dao的实现类里以前可能是继承SqlMapClientDaoSupport,现在要修改为继承BaseDaoiBatis

然后查询的时候
用super.getSqlMapClient().queryForList(id, parameterObject, skip, max)
四个参数分别对应ibatis配置文件里的id,查询时传入的对象参数,当前页及每页记录数
想得到查询完滴记录数,在service滴实现类里使用getObjectTotal(selectQuery,parameterObject)或getObjectTotal(selectQuery)都可以
区别是带不带查询滴参数对象,selectQuery就是ibatis配置文件里的id~~

 

分享到:
评论

相关推荐

    spring3.0.3+ibatis2.3.4.7分页

    标题中的“spring3.0.3+ibatis2.3.4.7分页”指的是在Spring 3.0.3版本与iBATIS 2.3.4.7版本结合下实现的一种分页功能。这是一个常见的Java Web开发场景,其中Spring作为依赖注入和框架管理工具,iBATIS作为数据访问...

    ibatis2.3例子代码

    这个"ibatis2.3例子代码"是为了演示如何在实际项目中集成并使用iBatis进行数据操作。 首先,我们需要了解iBatis的核心概念。主要包括XML配置文件、SQL映射文件、SqlSession和Mapper接口。XML配置文件通常包含数据库...

    ibatis2.3-src

    iBatis支持JDBC和Spring的事务管理,可以根据配置决定是否使用全局事务或本地事务。 8. **插件机制** iBatis允许开发者创建自定义插件,拦截Executor、StatementHandler、ParameterHandler、ResultSetHandler等...

    ibatis2.3 jar包

    虽然Ibatis后续版本(如3.x)引入了许多新特性,如注解支持、更强大的XML配置、更多类型的参数映射等,但2.3版本依然在很多项目中被使用,因为它简洁、稳定,对于小型项目或对性能要求不高的应用来说已经足够。...

    ibatis2.3.4.8.jar 和 ibatis-2.3.4.726.jar两个版本的下载

    在本主题中,我们将深入探讨Ibatis的两个特定版本:ibatis2.3.4.8.jar和ibatis-2.3.4.726.jar。 Ibatis的核心概念包括映射器(Mapper)、SQL映射文件和SqlSession。映射器是Ibatis的主要组件,它定义了数据库操作与...

    struts2_spring2.5_ibatis2.3_mysql架构

    *架构struts2_spring2.5_ibatis2.3 *mysql5.0 *jdk 1.6 *带有所有jar包,可直接运行 本实例实现了用户登陆,用户信息CRUD相关操作。让你感受到了ibatis做o/r mapping的方便快捷。 下次集成dwr进来 create ...

    ibatis2.3 jar (ibatis pdf 教程)

    **Ibatis 2.3 Jar 文件详解** Ibatis 是一款著名的Java持久层框架,它将SQL语句与Java代码分离,使得开发者可以更加灵活地控制SQL执行,同时保持了DAO层的良好封装。在Ibatis 2.3版本中,这个理念得到了充分的体现...

    ibatis2.3.chm

    ibatis2.3 api,chm 格式,方面快速查询ibatis 的相关接口

    iBATIS2.3-JavaDoc.rar

    这个压缩包“iBATIS2.3-JavaDoc.rar”包含了iBATIS 2.3版本的Java文档,通常以CHM(Compiled Help Manual)格式提供,方便开发者查阅API和了解其功能。JavaDoc是一种用于生成API文档的工具,它从Java源代码中的注释...

    ibatis2.3.4.726.jar

    ibatis2.3.4.726.jar ibatis2.3.4.726.jar ibatis2.3.4.726.jar ibatis2.3.4.726.jar

    ibatis2.3.4.8.jar 下载

    提供ibatis2.3.4.8.jar包下载.

    ibatis2.3.4.726增删改查源码实例

    在本实例中,"ibatis2.3.4.726增删改查源码实例" 提供了一个完整的基于Ibatis 2.3.4.726版本的开发案例,涵盖了数据库的基本操作,即增(INSERT)、删(DELETE)、改(UPDATE)和查(SELECT)。 首先,我们来了解...

    ibatis2.3 API.CHM

    ibatis2.3 API CHM 帮助文档 ibatis 开发人员必备

    iBATIS2.3及其说明文档

    iBATIS 3(MyBatis)是一个升级版,它在iBATIS的基础上进行了改进,引入了更多的新特性,如注解支持、更强的类型安全、更灵活的SQL构造等。学习文档将帮助你理解如何在iBATIS 3中使用这些新特性。 在使用iBATIS进行...

    对IBatis分页的改进,使ibatis支持hibernate式的物理分页

    公司的大部分项目都开始使用IBatis作为O/R Mapping了,但是在使用的过程中也发现了很多不方便和存在...想了很多办法,都没能很好的避免这个问题,无意间在javaeye上看到了《使ibatis支持hibernate式的物理分页》这篇文章,

    ibatis-2.3.4.726.jar,ibatis-2.3.0.677.jar,ibatis-2.3.3.720.jar下载

    这里提到的是iBATIS的三个不同版本的jar包:ibatis-2.3.4.726.jar、ibatis-2.3.0.677.jar以及ibatis-2.3.3.720.jar。 首先,让我们深入了解iBATIS的核心概念和功能: 1. **SQL Map配置**:iBATIS的核心是SQL Map...

    iBATIS 2.3 API JavaDoc chm格式

    6. **Dynamic SQL**:iBATIS支持动态SQL,允许在SQL语句中使用条件判断,提高SQL的灵活性和可维护性。 7. **Transactions**:iBATIS提供了事务管理功能,可以控制SQL操作的原子性,确保数据的一致性。 8. **Cache*...

    iBATIS-DAO-2.3.4.726.rar_com.ibatis.dao_iBATIS dao 2_iBatis DAO_

    在这个2.3.4.726版本的源码中,我们可以深入理解iBATIS DAO的工作原理,并通过添加注释来帮助我们更好地掌握其实现细节。 首先,iBATIS DAO的核心概念是SQL Maps,它们定义了数据库操作的SQL语句,并将其映射到Java...

    Struts2+Spring2.5+Ibatis2.3架构

    Struts2+Spring2.5+Ibatis2.3架构是一种经典的Java Web开发技术栈,广泛应用于企业级应用系统中。这个架构结合了Struts2的MVC框架、Spring的依赖注入(DI)和面向切面编程(AOP)以及Ibatis的持久层解决方案,为...

Global site tag (gtag.js) - Google Analytics