您的位置:首页 > 其它

MyBatis使用(二)分页查询

2015-08-31 11:33 459 查看
由于MyBatis没有相关的分页查询,因此抽取出hibernate的分页查询功能,通过过滤器,对本地sql方言进行区分,对sql语句进行拼接和封装

步骤分为:1、先查询出总数

     2、通过拼接的sql再去查询相关信息

/**
* 带有分页信息的查询
* @param sqlMapId mybatis映射id
* @param pageRequest 分页请求参数信息
* @return
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public Page findForPage(String sqlMapId, PageRequest pageRequest) {

// 查询总数
pageRequest.getFilters().put(SelectCountSqlInterceptor.COUNT, null); // 设置是否需要将sql转换成总数查询sql
Number totalCount = (Number) findForObject(sqlMapId, pageRequest
.getFilters());
if (totalCount == null || totalCount.intValue() <= 0) {
return new Page(pageRequest, 0);
}
if(totalCount != null && totalCount.intValue() <= (pageRequest.getPageNumber()-1) * pageRequest.getPageSize()){
return new Page(pageRequest.getPageNumber(), pageRequest.getPageSize(), totalCount.intValue(), new ArrayList(0));
}
pageRequest.getFilters().remove(SelectCountSqlInterceptor.COUNT);

Map filters = new HashMap();
filters.putAll(pageRequest.getFilters());
Page page = new Page(pageRequest, totalCount.intValue());
List list = findForList(sqlMapId, filters, page.getFirstResult(), page.getPageSize());

page.setResult(list);

return page;
}


  

/**
* 分页请求信息
*/
public class PageRequest implements Serializable {

private static final long serialVersionUID = 9092186838918641382L;

/**
* 过滤参数
*/
private Map filters;

/**
* 页号码,页码从1开始
*/
private int pageNumber;

/**
* 分页大小
*/
private int pageSize;
}


  

/**
* 将查询SQL转成查询总数SQL<br>
*
* 配置文件内容:
*
* <pre>
* 	<plugins>
* 		<plugin interceptor="ewell.nis.common.ibatis.plugin.SelectCountSqlInterceptor"/>
* 	</plugins>
* </pre>
*/
@Intercepts( { @Signature(type = Executor.class, method = "query", args = {
MappedStatement.class, Object.class, RowBounds.class,
ResultHandler.class }) })
public class SelectCountSqlInterceptor implements Interceptor {

public static String COUNT = "_count";

private static int MAPPED_STATEMENT_INDEX = 0;

private static int PARAMETER_INDEX = 1;

@Override
public Object intercept(Invocation invocation) throws Throwable {

processCountSql(invocation.getArgs());

return invocation.proceed();
}

private void processCountSql(final Object[] queryArgs) {

if (queryArgs[PARAMETER_INDEX] instanceof Map) {
Map parameter = (Map) queryArgs[PARAMETER_INDEX];
if (parameter.containsKey(COUNT)) {
MappedStatement ms = (MappedStatement) queryArgs[MAPPED_STATEMENT_INDEX];
BoundSql boundSql = ms.getBoundSql(parameter);
String sql = ms.getBoundSql(parameter).getSql().trim();
BoundSql newBoundSql = new BoundSql(ms.getConfiguration(),
getCountSQL(sql), boundSql.getParameterMappings(),
boundSql.getParameterObject());
MappedStatement newMs = copyFromMappedStatement(ms,
new BoundSqlSqlSource(newBoundSql));
queryArgs[MAPPED_STATEMENT_INDEX] = newMs;
}
}
}

// see: MapperBuilderAssistant
private MappedStatement copyFromMappedStatement(MappedStatement ms,
SqlSource newSqlSource) {

Builder builder = new MappedStatement.Builder(ms.getConfiguration(), ms
.getId(), newSqlSource, ms.getSqlCommandType());

builder.resource(ms.getResource());
builder.fetchSize(ms.getFetchSize());
builder.statementType(ms.getStatementType());
builder.keyGenerator(ms.getKeyGenerator());
builder.keyProperty(getKeyProperty(ms.getKeyProperties()));

// setStatementTimeout()
builder.timeout(ms.getTimeout());

// setParameterMap()
builder.parameterMap(ms.getParameterMap());

// setStatementResultMap()
List<ResultMap> resultMaps = new ArrayList<ResultMap>();
String id = "-inline";
if (ms.getResultMaps() != null) {
id = ms.getResultMaps().get(0).getId() + "-inline";
}
ResultMap resultMap = new ResultMap.Builder(null, id, Long.class,
new ArrayList()).build();
resultMaps.add(resultMap);
builder.resultMaps(resultMaps);
builder.resultSetType(ms.getResultSetType());

// setStatementCache()
builder.cache(ms.getCache());
builder.flushCacheRequired(ms.isFlushCacheRequired());
builder.useCache(ms.isUseCache());

return builder.build();
}

private String getKeyProperty(String[] keyProperties) {

StringBuilder builder = new StringBuilder();
if (keyProperties != null && keyProperties.length > 0) {
int length = keyProperties.length;
for (int i = 0; i < length; i++) {
builder.append(keyProperties[i]);
if (i < length -1) {
builder.append(",");
}
}
return builder.toString();
}

return null;
}

private String getCountSQL(String sql) {

String lowerCaseSQL = sql.toLowerCase().replace("\n", " ").replace(
"\t", " ");
int index = lowerCaseSQL.indexOf(" order ");

if (index != -1) {
sql = sql.substring(0, index);
}

if (lowerCaseSQL.indexOf(" group ") != -1) {
return "SELECT COUNT(*) FROM (SELECT COUNT(*) AS COUNT_" + sql.substring(lowerCaseSQL.indexOf(" from ")) + ") TABLE_";
}

return "SELECT COUNT(*) AS COUNT_" + sql.substring(lowerCaseSQL.indexOf(" from "));
}

@Override
public Object plugin(Object target) {

return Plugin.wrap(target, this);
}

@Override
public void setProperties(Properties properties) {

}
}


  

/**
* 为ibatis3提供基于方言(Dialect)的分页查询的插件<br>
*
* 将拦截Executor.query()方法实现分页方言的插入<br>
*
* 配置文件内容:
*
* <pre>
* 	<plugins>
* 	<plugin interceptor="ewell.nis.common.ibatis.plugin.OffsetLimitInterceptor">
* 		<property name="dialectClass" value="ewell.nis.common.ibatis.dialect.MySQLDialect"/>
* 	</plugin>
* </plugins>
* </pre>
*
*
*/

@Intercepts( { @Signature(type = Executor.class, method = "query", args = {
MappedStatement.class, Object.class, RowBounds.class,
ResultHandler.class }) })
public class OffsetLimitInterceptor implements Interceptor {

private static int MAPPED_STATEMENT_INDEX = 0;

private static int PARAMETER_INDEX = 1;

private static int ROWBOUNDS_INDEX = 2;

private Dialect dialect;

@Override
public Object intercept(Invocation invocation) throws Throwable {

processIntercept(invocation.getArgs());
return invocation.proceed();
}

void processIntercept(final Object[] queryArgs) {

// queryArgs = query(MappedStatement ms, Object parameter, RowBounds
// rowBounds, ResultHandler resultHandler)
MappedStatement ms = (MappedStatement) queryArgs[MAPPED_STATEMENT_INDEX];
Object parameter = queryArgs[PARAMETER_INDEX];
final RowBounds rowBounds = (RowBounds) queryArgs[ROWBOUNDS_INDEX];
int offset = rowBounds.getOffset();
int limit = rowBounds.getLimit();

if (dialect.supportsLimit()
&& (offset != RowBounds.NO_ROW_OFFSET || limit != RowBounds.NO_ROW_LIMIT)) {
BoundSql boundSql = ms.getBoundSql(parameter);
String sql = boundSql.getSql().trim();
if (dialect.supportsLimitOffset()) {
sql = dialect.getLimitString(sql, offset, limit);
offset = RowBounds.NO_ROW_OFFSET;
}
else {
sql = dialect.getLimitString(sql, 0, offset+limit);
}
limit = RowBounds.NO_ROW_LIMIT;

queryArgs[ROWBOUNDS_INDEX] = new RowBounds(offset, limit);
BoundSql newBoundSql = new BoundSql(ms.getConfiguration(), sql,
boundSql.getParameterMappings(), boundSql
.getParameterObject());
MappedStatement newMs = copyFromMappedStatement(ms,
new BoundSqlSqlSource(newBoundSql));
queryArgs[MAPPED_STATEMENT_INDEX] = newMs;
}
}

// see: MapperBuilderAssistant
private MappedStatement copyFromMappedStatement(MappedStatement ms,
SqlSource newSqlSource) {

Builder builder = new MappedStatement.Builder(ms.getConfiguration(), ms
.getId(), newSqlSource, ms.getSqlCommandType());

builder.resource(ms.getResource());
builder.fetchSize(ms.getFetchSize());
builder.statementType(ms.getStatementType());
builder.keyGenerator(ms.getKeyGenerator());
builder.keyProperty(getKeyProperty(ms.getKeyProperties()));

// setStatementTimeout()
builder.timeout(ms.getTimeout());

// setStatementResultMap()
builder.parameterMap(ms.getParameterMap());

// setStatementResultMap()
builder.resultMaps(ms.getResultMaps());
builder.resultSetType(ms.getResultSetType());

// setStatementCache()
builder.cache(ms.getCache());
builder.flushCacheRequired(ms.isFlushCacheRequired());
builder.useCache(ms.isUseCache());

return builder.build();
}

public Object plugin(Object target) {

return Plugin.wrap(target, this);
}

public void setProperties(Properties properties) {

String dialectClass = new PropertiesHelper(properties)
.getRequiredString("dialectClass");
try {
dialect = (Dialect) Class.forName(dialectClass).newInstance();
} catch (Exception e) {
throw new RuntimeException(
"cannot create dialect instance by dialectClass:"
+ dialectClass, e);
}
System.out.println(OffsetLimitInterceptor.class.getSimpleName()
+ ".dialect=" + dialectClass);
}

private String getKeyProperty(String[] keyProperties) {

StringBuilder builder = new StringBuilder();
if (keyProperties != null && keyProperties.length > 0) {
int length = keyProperties.length;
for (int i = 0; i < length; i++) {
builder.append(keyProperties[i]);
if (i < length -1) {
builder.append(",");
}
}
return builder.toString();
}

return null;
}

public static class BoundSqlSqlSource implements SqlSource {

private BoundSql boundSql;

public BoundSqlSqlSource(BoundSql boundSql) {

this.boundSql = boundSql;
}

public BoundSql getBoundSql(Object parameterObject) {

return boundSql;
}
}
}


  

  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: