All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sicheng.common.persistence.proxy.PaginationMapperMethod Maven / Gradle / Ivy

There is a newer version: 4.1.1
Show newest version
/**
 * 本作品使用 木兰公共许可证,第2版(Mulan PubL v2) 开源协议,请遵守相关条款,或者联系sicheng.net获取商用授权。
 * Copyright (c) 2016 SiCheng.Net
 * This software is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */
package com.sicheng.common.persistence.proxy;

import com.sicheng.common.persistence.Page;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.binding.BindingException;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSession;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 

* 执行代理类,扩展Mybatis的方式来让其Mapper接口来支持. *

* * @author zhaolei * @version 1.0 2012-05-13 上午10:09 * */ public class PaginationMapperMethod { private final SqlSession sqlSession; private final Configuration config; private SqlCommandType type; private String commandName; private String commandCountName; private final Class declaringInterface; private final Method method; private Integer rowBoundsIndex; private Integer paginationIndex; private final List paramNames; private final List paramPositions; private boolean hasNamedParameters; public PaginationMapperMethod(Class declaringInterface, Method method, SqlSession sqlSession) { paramNames = new ArrayList(); paramPositions = new ArrayList(); this.sqlSession = sqlSession; this.method = method; this.config = sqlSession.getConfiguration(); this.declaringInterface = declaringInterface; this.hasNamedParameters = false; setupFields(); setupMethodSignature(); setupCommandType(); validateStatement(); } /** * 代理执行方法。 * * @param args 参数信息 * @return 执行结果 */ @SuppressWarnings("unchecked") public Object execute(Object[] args) { final Object param = getParam(args); Page page; RowBounds rowBounds; if (paginationIndex != null) { page = (Page) args[paginationIndex]; rowBounds = new RowBounds(page.getFirstResult(), page.getMaxResults()); } else if (rowBoundsIndex != null) { rowBounds = (RowBounds) args[rowBoundsIndex]; page = new Page(); } else { throw new BindingException("Invalid bound statement (not found rowBounds or pagination in paramenters)"); } page.setCount(executeForCount(param)); page.setList(executeForList(param, rowBounds)); return page; } /** * 执行总数的方法,调用方法执行计算总数,取得总结果 * * @param param 参数信息 * @return 查询的总记录数 */ private long executeForCount(Object param) { Number result = (Number) sqlSession.selectOne(commandCountName, param); return result.longValue(); } /** * 取得分页的执行结果,返回的是纪录信息 * * @param param 参数 * @param rowBounds row * @return 纪录列表 */ private List executeForList(Object param, RowBounds rowBounds) { return sqlSession.selectList(commandName, param, rowBounds); } /** * 取得当前执行的参数信息 * * @param args 参数 * @return 参数信息 */ private Object getParam(Object[] args) { final int paramCount = paramPositions.size(); if (args == null || paramCount == 0) { return null; } else if (!hasNamedParameters && paramCount == 1) { return args[paramPositions.get(0)]; } else { Map param = new HashMap(); for (int i = 0; i < paramCount; i++) { param.put(paramNames.get(i), args[paramPositions.get(i)]); } return param; } } private void setupMethodSignature() { final Class[] argTypes = method.getParameterTypes(); for (int i = 0; i < argTypes.length; i++) { if (Page.class.isAssignableFrom(argTypes[i])) { paginationIndex = i; } else if (RowBounds.class.isAssignableFrom(argTypes[i])) { rowBoundsIndex = i; } else { String paramName = String.valueOf(paramPositions.size()); paramName = getParamNameFromAnnotation(i, paramName); paramNames.add(paramName); paramPositions.add(i); } } } private String getParamNameFromAnnotation(int i, String paramName) { Object[] annotations = method.getParameterAnnotations()[i]; for (Object annotation : annotations) { if (annotation instanceof Param) { hasNamedParameters = true; paramName = ((Param) annotation).value(); } } return paramName; } /** * 设置当前的查询总记录数的ID */ private void setupFields() { commandName = declaringInterface.getName() + "." + method.getName(); commandCountName = commandName + "Count"; // 命名约定 } /** * 设置当前的参数的类型信息 */ private void setupCommandType() { MappedStatement ms = config.getMappedStatement(commandName); type = ms.getSqlCommandType(); if (type != SqlCommandType.SELECT) { throw new BindingException("Unsupport execution method for: " + commandName); } } /** * 验证Statement */ private void validateStatement() { if (!config.hasStatement(commandName)) { throw new BindingException("Invalid bound statement (not found): " + commandName); } if (!config.hasStatement(commandCountName)) { throw new BindingException("Invalid bound statement (not found): " + commandCountName); } } }