IBatis框架的一些问题的扩展(四)

由于Ibatis的分页采用逻辑分页通过针对Ibatis分页的特殊处理支持物理分页。

实现思路:由于Ibatis各种数据操纵最终要调用SqlExecutor实现各种数据操作的功能。通过重写SqlExecutor 中特定的方法实现,相关的功能。

 

SqlExecutor 源码中通过逻辑分页调用

public void executeQuery(StatementScope statementScope, Connection conn, String sql, Object parameters[], int skipResults, int maxResults, RowHandlerCallback callback)

        throws SQLException;

 

通过自定义扩展的IbatisSqlExecutor类:

package com.framework.app.ibatis;

import java.sql.Connection;

import java.sql.SQLException;

import com.ibatis.sqlmap.engine.execution.SqlExecutor;

import com.ibatis.sqlmap.engine.mapping.statement.RowHandlerCallback;

import com.ibatis.sqlmap.engine.scope.StatementScope;

 

public class LimitSqlExecutor extends SqlExecutor {

    private Dialect dialect;

    private boolean enableLimit = true;

    public Dialect getDialect() {

        return dialect;

    }

    public void setDialect(Dialect dialect) {

        if (dialect != null) {

            System.out.println("[iBATIS] 设置 ibatis LimitSqlExecutor.dialect = "

                    + dialect.getClass().getName());

        }

        this.dialect = dialect;

    }

    public boolean isEnableLimit() {

        return enableLimit;

    }

    public void setEnableLimit(boolean enableLimit) {

        this.enableLimit = enableLimit;

    }

    public void executeQuery(StatementScope request, Connection conn, String sql,

            Object[] parameters, int skipResults, int maxResults,

            RowHandlerCallback callback) throws SQLException {

        String limitSql = sql;

        int changedSkipResults = skipResults;

        int changedMaxResults = maxResults;

        if (supportsLimit()

                && (skipResults != NO_SKIPPED_RESULTS || maxResults != NO_MAXIMUM_RESULTS)) {

            limitSql = limitSql.trim();

            if (dialect.supportsLimitOffset()) {

                limitSql = dialect.getLimitString(sql, skipResults, maxResults);

                changedSkipResults = NO_SKIPPED_RESULTS;

            } else {

                limitSql = dialect.getLimitString(sql, 0, maxResults);

            }

            changedMaxResults = NO_MAXIMUM_RESULTS;

        }

        super.executeQuery(request, conn, limitSql, parameters,

                changedSkipResults, changedMaxResults, callback);

    }

    public boolean supportsLimit() {

        if (enableLimit && dialect != null) {

            return dialect.supportsLimit();

        }

        return false;

    }

}

 

使用如下:

通过注入的方式将重新自定的LimitSqlExecutor注入的SqlExecutor

 

	@Override
	@SuppressWarnings({ "unchecked", "deprecation" })
	public Pagination queryForPaginatedList(String itemSqlId,
			String countSqlId, Object parameter, int skip, int max) {
		if (sqlMapClient instanceof ExtendedSqlMapClient) {
			LimitSqlExecutor limitSqlExecutor = new LimitSqlExecutor();
			limitSqlExecutor.setDialect(new OracleDialect());
			RefUtils.setFieldValue(((ExtendedSqlMapClient) sqlMapClient)
					.getDelegate(), "sqlExecutor", SqlExecutor.class,
					limitSqlExecutor);
		}

		try {
			// 偏移值
			int offset = (skip - 1) * max;
			// 数据项
			List listItem = sqlMapClient.queryForList(itemSqlId, parameter,
					offset, max);
			// 总页数
			int totalResult = queryForTotalResult(countSqlId, parameter);
			return new Pagination(listItem, totalResult, offset, max);
		} catch (SQLException e) {
			e.printStackTrace();
			throw new DAOException(e);
		}
	}

 

 

 备注:这种方法不是很好,但是考虑到执行分页的方法不是很多,所以就这样了,最好采用在类加载器类对垒的重新加载时注入相关的类,可能更好。

你可能感兴趣的:(sql,框架,ibatis)