本文共 11417 字,大约阅读时间需要 38 分钟。
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) { // 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) { postProcessParameterObje ct(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(); } } 转载于:https://my.oschina.net/softwarechina/blog/123318