`
wuyunlong
  • 浏览: 9475 次
  • 来自: ...
文章分类
社区版块
存档分类
最新评论

分页查询的实现

阅读更多
看到robbin的"应用Hibernate3的DetachedCriteria实现分页查询",我把最近的写的关于
分页方法的算法拿出来现一下丑,还请大家手下留情,^_^

1.PaginationMethod.java
package com.airinbox.pagination;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 用于标识支持分页的方法,如果一个类中有多个用PaginationMethod标识的方法,请指定name,否则将
 * 不能正确的得到方法。另外此注释支持从超类或者接口中查询此注释类型。
 * @author wuyunlong
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface PaginationMethod {
	/**
	 * 为此方法指定的名称。
	 * 
	 * @return 返回方法的名称。
	 */
	public String name() default "";

	/**
	 * 在方法中记录偏移量的参数位置,默认为0。
	 * 
	 * @return 返回方法中记录偏移量的参数位置。
	 */
	public int offsetParamIndex() default 0;

	/**
	 * 在方法中记录最大返回长度的参数位置,默认为1。
	 * 
	 * @return
	 */
	public int maxLengthParamIndex() default 1;

	/**
	 * 用户表示返回的列表中是否全部的元素还是分页的元素。
	 * 
	 * @return 返回true,表示全部元素,此时offsetParamIndex和maxLengthParamIndex的值将
	 * 		不会再起作用;否则表示返回分页的元素。
	 */
	public boolean all() default false;
}



2.Pagination.java
package com.airinbox.pagination;

import java.util.Collection;

/**
 * 分页导航属性信息。
 * 
 * @author wuyunlong
 * 
 * @param <T>
 *            Method的返回集合(目前只支持数组类型和java.util.Collection类型急子类型的返 
 *            回类型)中元素的类型。
 */
public interface Pagination {
	/**
	 * 返回结果,则这个被包装成了Collection类型。
	 * @return 
	 */
	public Collection<?> getMethodReturnValue();
	/**
	 * 表示是否有下一页。
	 * @return
	 */
	public boolean hasNext();
	/**
	 * 用户判断是否有前页。
	 * @return 布尔值。
	 */
	public boolean hasBefore();
	
	public int getCurrentPageNumber();
	
	/**
	 * n的默认值,为1。
	 */
	public static final int DEFAULT_N = 1;
	/**
	 * 判断是否包含上n页的值。
	 * @return 布尔值。
	 */
	public boolean hasFollowingSeveralPages();
	/**
	 * 判断是否包含下n页的值。
	 * @return 布尔值。
	 */
	public boolean hasFormerSeveralPages();	
	
	public int getFollowingSeveralPagesNumberMax();
	/**
	 * 获取第一条记录的偏移量。
	 * @return
	 */
	public int getStartOffset();	
}



3.PageinationBuilder.java

package com.airinbox.pagination;

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

/**
 * 分页导航构造器。
 * 
 * @author wuyunlong
 * 
 */
class PageinationBuilder {
	private final static Map<String, MethodInfo> METHODINFO_CACHE;

	static {
		METHODINFO_CACHE = new HashMap<String, MethodInfo>();
	}

	private final static int PAGE_NUMBER_MIN_VALUE = 1;

	/**
	 * 页码。
	 */
	private final int currentPageNumber;

	/**
	 * 每页里面包含记录的最大条数。
	 */
	private final int pageSize;

	/**
	 * 包含支持分页方法的对象的实例。
	 */
	private Object instance;

	/**
	 * 支持的分页方法的在{@link PaginationMethod}中的名称。
	 */
	private String name;

	/**
	 * 除了偏移量,最大长度之外的参数。
	 */
	private Object[] otherParameters;

	/**
	 * 分页方法的返回值。
	 */
	private Object returnValue;

	/**
	 * 上下n页的n值。
	 */
	private final int severalPagesNumber;

	/**
	 * 分页方法的信息。
	 */
	private MethodInfo methodInfo;

	/**
	 * 第一页开始记录的偏移量。
	 */
	private final int offset;

	/**
	 * 返回列表中第一个记录的索引值。
	 */
	private int firstReturnedOffset;

	/**
	 * 返回列表的最大长度。
	 */
	private int maxLength;

	/**
	 * 返回列表的实际需要最大长。
	 */
	private int checkoutMaxLength;
	/**
	 * 第一个输出元素在方法的返回列表中的位置。
	 */
	private int cur;
	/**
	 * 做大页码值。
	 */
	private final int maxPageNumber;

	/**
	 * 构造函数。
	 * 
	 * @param page
	 *            页码,从1开始的整数值。
	 * @param pageSize
	 *            每页里面包含记录的最大条数。
	 * @param maxPageNumber
	 *            最多显示的页码。
	 * @param offset
	 *            第一页开始记录的偏移量。
	 * @param severalPagesNumber
	 *            上下n页的n值。
	 * @param instance
	 *            包含支持分页方法的对象的实例。
	 * @param name
	 *            支持的分页方法的在{@link PaginationMethod}中的名称。
	 * @param otherParameters
	 *            除了偏移量,最大长度之外的参数值(按照原有的顺序排列)。
	 * @throws NullPointerException
	 *             如果instance为null,则抛出此异常。
	 * @throws MethodConfigurationException
	 *             PaginationMethod中参数配置错误或者在目标方法返回值既不是数组也不是{@link Collection}。
	 */
	public PageinationBuilder(int page, int pageSize, int maxPageNumber,
			int offset, int severalPagesNumber, Object instance, String name,
			Object... otherParameters) throws NullPointerException,
			MethodConfigurationException {
		super();
		if (instance == null)
			throw new NullPointerException("实例不能为空");
		this.name = name;
		this.instance = instance;
		methodInfo = checkoutMethodInfo();
		this.maxPageNumber = maxPageNumber;
		this.currentPageNumber = checkoutRealPage(page, maxPageNumber);
		this.pageSize = checkoutPageSize(pageSize);
		this.offset = checkoutRealOffset(offset);
		firstReturnedOffset = (this.currentPageNumber - 1) * this.pageSize
				+ this.offset;

		if (methodInfo.getMethodMeta().all()) {
			this.cur = firstReturnedOffset;
		} else {
			this.cur = 0;
		}

		this.otherParameters = otherParameters;
		this.severalPagesNumber = checkoutSeveralPagesNumber(severalPagesNumber);
		if(currentPageNumber + this.severalPagesNumber > this.maxPageNumber){
			if(this.currentPageNumber == this.maxPageNumber){
				this.maxLength = this.pageSize;
				this.checkoutMaxLength = this.pageSize;
			}else{
				maxLength = this.pageSize * (this.maxPageNumber - currentPageNumber);
				checkoutMaxLength = maxLength + 1;
			}
		}else{
			maxLength = this.pageSize * this.severalPagesNumber;
			checkoutMaxLength = maxLength + 1;
		}
	}

	/**
	 * 构造函数。
	 * 
	 * @param page
	 *            页码,从1开始的整数值。
	 * @param pageSize
	 *            每页里面包含记录的最大条数。
	 * @param offset
	 *            第一页开始记录的偏移量。
	 * @param severalPagesNumber
	 *            上下n页的n值。
	 * @param instance
	 *            包含支持分页方法的对象的实例。
	 * @param name
	 *            支持的分页方法的在{@link PaginationMethod}中的名称。
	 * @param otherParameters
	 *            除了偏移量,最大长度之外的参数值(按照原有的顺序排列)。
	 * @throws NullPointerException
	 *             如果instance为null,则抛出此异常。
	 * @throws MethodConfigurationException
	 *             PaginationMethod中参数配置错误或者在目标方法返回值既不是数组也不是{@link Collection}。
	 */
	public PageinationBuilder(int page, int pageSize, int offset,
			int severalPagesNumber, Object instance, String name,
			Object... otherParameters) throws NullPointerException,
			MethodConfigurationException {
		this(page, pageSize, Integer.MAX_VALUE, offset, severalPagesNumber,
				instance, name, otherParameters);
	}

	/**
	 * 取出可用的每页里面包含记录的最大条数
	 * 
	 * @param size
	 *            用户输入的页码值。
	 * @return 返回实际可用的每页里面包含记录的最大条数。
	 */
	private int checkoutPageSize(int size) {
		return size > 0 ? size : 5;
	}

	/**
	 * 取出可用的第一页开始记录的偏移量。
	 * 
	 * @param offset
	 *            第一页开始记录的偏移量。
	 * @return 返回可用的第一页开始记录的偏移量。
	 */
	private int checkoutRealOffset(int offset) {
		return offset >= 0 ? offset : 0;
	}

	/**
	 * 取出可用的页码。
	 * 
	 * @param page
	 *            用户输入的页码。
	 * @return 返回可用的页码。
	 */
	private int checkoutRealPage(int page, int maxValue) {
		if (page > maxValue)
			return PAGE_NUMBER_MIN_VALUE;
		return page >= PAGE_NUMBER_MIN_VALUE ? page : PAGE_NUMBER_MIN_VALUE;
	}

	private int checkoutSeveralPagesNumber(int n) {
		return n > 0 ? n : 1;
	}

	private MethodInfo checkoutMethodInfo() throws MethodConfigurationException {
		MethodInfo am = lookupMethodInfo(instance.getClass());
		if (am == null) {
			throw new MethodConfigurationException("在"
					+ instance.getClass().getName()
					+ "中没有找到注释为PaginationMethod(name=\"" + name + "\")的方法");
		}
		return am;
	}

	private boolean implement(Class<?> type, Class<?> interf) {
		Class<?>[] superInterf = type.getInterfaces();
		for (Class<?> clazz : superInterf) {
			if (clazz.equals(interf))
				return true;
		}
		return false;
	}

	public Pagination invoke() throws MethodConfigurationException {
		try {
			Object[] parameters = buildParameters();
			returnValue = methodInfo.getMethod().invoke(instance, parameters);
		} catch (Exception e) {
			throw new MethodConfigurationException(e);
		}
		return createPagination();
	}

	private Object[] buildParameters() throws MethodConfigurationException {
		List<Object> list = new ArrayList<Object>();
		for (Object object : otherParameters) {
			list.add(object);
		}
		insertParameters(list);
		return list.toArray(new Object[0]);
	}

	private void insertParameters(List<Object> paramList)
			throws MethodConfigurationException {
		PaginationMethod meta = methodInfo.getMethodMeta();
		if (!meta.all()) {
			try {
				int osi = meta.offsetParamIndex();
				int mli = meta.maxLengthParamIndex();
				if (osi < mli) {
					paramList.add(osi, firstReturnedOffset);
					paramList.add(mli, checkoutMaxLength);
				} else {
					paramList.add(mli, checkoutMaxLength);
					paramList.add(osi, firstReturnedOffset);
				}
			} catch (IndexOutOfBoundsException e) {
				throw new MethodConfigurationException(e);
			}
		}
	}

	private MethodInfo lookupMethodInfo(Class<?> type)
			throws MethodConfigurationException {
		MethodInfo ret = null;
		final String key = type.getName() + "@PaginationMethod(name=\"" + name
				+ "\")";
		synchronized (METHODINFO_CACHE) {
			ret = METHODINFO_CACHE.get(key);
		}
		if (ret != null) {
			return ret;
		} else {
			synchronized (METHODINFO_CACHE) {
				if (METHODINFO_CACHE.containsKey(key))
					return null;
			}
		}
		ret = lookupMethodInfoFromClass(type);
		synchronized (METHODINFO_CACHE) {
			METHODINFO_CACHE.put(key, ret);
		}
		return ret;
	}

	private MethodInfo lookupMethodInfoFromClass(Class<?> type)
			throws MethodConfigurationException {
		MethodInfo ret = null;
		Method[] methodArr = type.getMethods();
		for (Method method : methodArr) {
			PaginationMethod pd = method.getAnnotation(PaginationMethod.class);
			if (pd == null)
				continue;
			if (name.equals(pd.name())) {
				ret = new MethodInfo();
				boolean isCollection = false;
				Class<?> returnType = method.getReturnType();
				if (!(isCollection = implement(returnType, Collection.class))
						&& !returnType.isArray()) {
					throw new MethodConfigurationException(name
							+ "的返回类型应该是Collection或者数组");
				}
				ret.setReturnValueInstanceOfCollection(isCollection);
				ret.setMethod(method);
				ret.setMethodMeta(pd);
				break;
			}
			if (ret != null) {
				break;
			}
		}
		if (ret != null)
			return ret;
		// 从超类中查询。
		if (ret == null && !type.isInterface()
				&& !type.getSuperclass().equals(Object.class)) {
			ret = lookupMethodInfoFromClass(type.getSuperclass());
		}
		// 从接口中查询。
		if (ret == null) {
			Class<?>[] sx = type.getInterfaces();
			for (Class<?> c : sx) {
				ret = lookupMethodInfoFromClass(c);
				if (ret != null) {
					break;
				}
			}
		}
		return ret;
	}

	private MethodReturnValueInfo getCollectionReturn() {
		Collection<?> c = (Collection<?>) returnValue;
		List<Object> list = new ArrayList<Object>();
		int realCount = c.size();
		if (cur < realCount) {
			int count = 0;
			int pos = 0;
			for (Iterator<?> iterator = c.iterator(); iterator.hasNext()
					&& count < pageSize;) {
				Object t = (Object) iterator.next();
				if (pos >= cur) {
					list.add(t);
					count++;
				}
				pos++;
			}
		}
		return new MethodReturnValueInfo(realCount, list);
	}

	private MethodReturnValueInfo getArrayReturn() {
		List<Object> list = new ArrayList<Object>();
		int realCount = Array.getLength(returnValue);
		int c = this.cur + pageSize;
		int end = c > realCount ? realCount : c;
		for (int i = this.cur; i < end; i++) {
			list.add(Array.get(returnValue, i));
		}
		return new MethodReturnValueInfo(realCount, list);
	}

	private Pagination createPagination() {
		DefaultPagination dp = new DefaultPagination();
		dp.setCurrentPageNumber(currentPageNumber);
		MethodReturnValueInfo mrvi = null;
		if (methodInfo.returnValueInstanceOfCollection()) {
			mrvi = getCollectionReturn();
		} else {
			mrvi = getArrayReturn();
		}
		dp.setMethodReturnValue(mrvi.getReturnValue());
		dp.setNext(mrvi.getRealCount() > pageSize + cur);
		dp.setFollowingSeveralPages(mrvi.getRealCount() > maxLength + cur);

		int d = mrvi.getRealCount() - cur;
		if (d > checkoutMaxLength) {
			d = checkoutMaxLength;
		}

		int mod = d % pageSize;
		int number = d / pageSize + (mod == 0 ? 0 : 1);
		dp.setFollowingSeveralPagesNumberMax(number);

		dp.setBefore(currentPageNumber > 1);
		dp.setFormerSeveralPages(currentPageNumber > severalPagesNumber);
		dp.setStartOffset(firstReturnedOffset);
		return dp;
	}

	private class MethodReturnValueInfo {
		private int realCount;
		private List<?> returnValue;

		public MethodReturnValueInfo(int realCount, List<?> returnValue) {
			super();
			this.realCount = realCount;
			this.returnValue = returnValue;
		}

		public int getRealCount() {
			return realCount;
		}

		public List<?> getReturnValue() {
			return returnValue;
		}

	}

	private static class DefaultPagination implements Pagination {
		private Collection<?> methodReturnValue;

		private boolean next;

		private boolean before;

		private boolean followingSeveralPages;

		private boolean formerSeveralPages;

		private int followingSeveralPagesNumberMax;

		private int firstRecorderOffset;

		private int currentPageNumber;

		public DefaultPagination() {
			super();
		}

		public void setMethodReturnValue(Collection<?> value) {
			this.methodReturnValue = value;
		}

		public Collection<?> getMethodReturnValue() {
			return methodReturnValue;
		}

		public void setNext(boolean value) {
			this.next = value;
		}

		public boolean hasNext() {
			return next;
		}

		public boolean hasBefore() {
			return before;
		}

		public void setBefore(boolean before) {
			this.before = before;
		}

		public boolean hasFollowingSeveralPages() {
			return followingSeveralPages;
		}

		public void setFollowingSeveralPages(boolean value) {
			this.followingSeveralPages = value;
		}

		public boolean hasFormerSeveralPages() {
			return formerSeveralPages;
		}

		public void setFormerSeveralPages(boolean value) {
			this.formerSeveralPages = value;
		}

		public int getFollowingSeveralPagesNumberMax() {
			return followingSeveralPagesNumberMax;
		}

		public void setFollowingSeveralPagesNumberMax(
				int followingSeveralPagesNumberMax) {
			this.followingSeveralPagesNumberMax = followingSeveralPagesNumberMax;
		}

		public int getStartOffset() {
			return firstRecorderOffset;
		}

		public void setStartOffset(int value) {
			firstRecorderOffset = value;
		}

		public int getCurrentPageNumber() {
			return currentPageNumber;
		}

		public void setCurrentPageNumber(int currentPageNumber) {
			this.currentPageNumber = currentPageNumber;
		}

	}

	private static class MethodInfo {
		private Method method;

		private PaginationMethod methodMeta;

		/**
		 * 分页方法的返回值是否是集合类型。
		 */
		private boolean returnValueInstanceOfCollection;

		public Method getMethod() {
			return method;
		}

		public void setMethod(Method method) {
			this.method = method;
		}

		public PaginationMethod getMethodMeta() {
			return methodMeta;
		}

		public void setMethodMeta(PaginationMethod methodMeta) {
			this.methodMeta = methodMeta;
		}

		public void setReturnValueInstanceOfCollection(boolean value) {
			this.returnValueInstanceOfCollection = value;
		}

		public boolean returnValueInstanceOfCollection() {
			return returnValueInstanceOfCollection;
		}
	}
}


4.PaginationFactory.java
package com.airinbox.pagination;

import java.util.Collection;

public class PaginationFactory {
	
	/**
	 * 创建分页导航。
	 * 
	 * @param page
	 *            页码,从1开始的整数值。
	 * @param pageSize
	 *            每页里面包含记录的最大条数。
	 * @param maxPage 
	 * 			分页时返回能够看到的最大页码数。
	 * @param offset
	 *            第一页开始记录的偏移量。
	 * @param severalPagesNumber
	 *            上下n页的n值。
	 * @param instance
	 *            包含支持分页方法的对象的实例。
	 * @param name
	 *            支持的分页方法的在{@link PaginationMethod}中的名称。
	 * @param otherParameters
	 *            除了偏移量,最大长度之外的参数值(按照原有的顺序排列)。
	 * @throws NullPointerException
	 *             如果instance为null,则抛出此异常。
	 * @throws MethodConfigurationException
	 *             PaginationMethod中参数配置错误或者在目标方法返回值既不是数组也不是{@link Collection}。
	 */
	public static Pagination createPagination(int page, int pageSize,int maxPage,
			int offset, int severalPagesNumber, Object instance, String name,
			Object... otherParameters) throws NullPointerException,
			MethodConfigurationException {
		PageinationBuilder pb = new PageinationBuilder(page, pageSize,maxPage,
				offset, severalPagesNumber, instance, name, otherParameters);
		return pb.invoke();
	}
	/**
	 * 创建分页导航。
	 * 
	 * @param page
	 *            页码,从1开始的整数值。
	 * @param pageSize
	 *            每页里面包含记录的最大条数。
	 * @param offset
	 *            第一页开始记录的偏移量。
	 * @param severalPagesNumber
	 *            上下n页的n值。
	 * @param instance
	 *            包含支持分页方法的对象的实例。
	 * @param name
	 *            支持的分页方法的在{@link PaginationMethod}中的名称。
	 * @param otherParameters
	 *            除了偏移量,最大长度之外的参数值(按照原有的顺序排列)。
	 * @throws NullPointerException
	 *             如果instance为null,则抛出此异常。
	 * @throws MethodConfigurationException
	 *             PaginationMethod中参数配置错误或者在目标方法返回值既不是数组也不是{@link Collection}。
	 */
	public static Pagination createPagination(int page, int pageSize,
			int offset, int severalPagesNumber, Object instance, String name,
			Object... otherParameters) throws NullPointerException,
			MethodConfigurationException {
		PageinationBuilder pb = new PageinationBuilder(page, pageSize,
				offset, severalPagesNumber, instance, name, otherParameters);
		return pb.invoke();
	}
	
	/**
	 * 创建分页导航,它同{@link #createPagination(int, int, int, int, Object, String, Object[])}
	 * 区别是:此方法用户于不包含otherParameters的分页导航。
	 * @param page
	 *            页码,从1开始的整数值。
	 * @param pageSize
	 *            每页里面包含记录的最大条数。
	 * @param offset
	 *            第一页开始记录的偏移量。
	 * @param severalPagesNumber
	 *            上下n页的n值。
	 * @param instance
	 *            包含支持分页方法的对象的实例。
	 * @param name
	 *            支持的分页方法的在{@link PaginationMethod}中的名称。	
	 * @throws NullPointerException
	 *             如果instance为null,则抛出此异常。
	 * @throws MethodConfigurationException
	 *             PaginationMethod中参数配置错误或者在目标方法返回值既不是数组也不是{@link Collection}。
	 */
	public static  Pagination createPagination2(int page, int pageSize,
			int offset, int severalPagesNumber, Object instance, String name)
			throws NullPointerException, MethodConfigurationException {
		return createPagination(page, pageSize, offset, severalPagesNumber,
				instance, name);
	}

	/**
	 * 创建分页导航,它同{@link #createPagination(int, int, int, int, Object, String, Object[])}
	 * 区别是:指定“第一页开始记录的偏移量”为0。
	 * @param page
	 *            页码,从1开始的整数值。
	 * @param pageSize
	 *            每页里面包含记录的最大条数。	
	 * @param severalPagesNumber
	 *            上下n页的n值。
	 * @param instance
	 *            包含支持分页方法的对象的实例。
	 * @param name
	 *            支持的分页方法的在{@link PaginationMethod}中的名称。	
	 * @param otherParameters
	 *            除了偏移量,最大长度之外的参数值(按照原有的顺序排列)。
	 * @throws NullPointerException
	 *             如果instance为null,则抛出此异常。
	 * @throws MethodConfigurationException
	 *             PaginationMethod中参数配置错误或者在目标方法返回值既不是数组也不是{@link Collection}。
	 */
	public static  Pagination createPagination3(int page, int pageSize,
			int severalPagesNumber, Object instance, String name,Object... otherParameters)
			throws NullPointerException, MethodConfigurationException {
		return createPagination(page, pageSize, 0, severalPagesNumber,
				instance, name,otherParameters);
	}
	
	/**
	 * 创建分页导航,它通{@link #createPagination(int, int, int, int, Object, String, Object[])}
	 * 区别是:此方法用户于不包含otherParameters的分页导航,并且指定“第一页开始记录的偏移量”
	 * 为0。
	 * @param page
	 *            页码,从1开始的整数值。
	 * @param pageSize
	 *            每页里面包含记录的最大条数。	
	 * @param severalPagesNumber
	 *            上下n页的n值。
	 * @param instance
	 *            包含支持分页方法的对象的实例。
	 * @param name
	 *            支持的分页方法的在{@link PaginationMethod}中的名称。		
	 * @throws NullPointerException
	 *             如果instance为null,则抛出此异常。
	 * @throws MethodConfigurationException
	 *             PaginationMethod中参数配置错误或者在目标方法返回值既不是数组也不是{@link Collection}。
	 */
	public static  Pagination createPagination4(int page, int pageSize,
			int severalPagesNumber, Object instance, String name)
			throws NullPointerException, MethodConfigurationException {
		return createPagination(page, pageSize, 0, severalPagesNumber,
				instance, name);
	}
	
	/**
	 * 创建分页导航,它通{@link #createPagination(int, int, int, int, Object, String, Object[])}
	 * 区别是:此方法用户于不包含otherParameters的分页导航,并且指定更多页中n值为{@link Pagination.DEFAULT_N}。
	 * @param page
	 *            页码,从1开始的整数值。
	 * @param pageSize
	 *            每页里面包含记录的最大条数。
	 * @param severalPagesNumber
	 *            上下n页的n值。
	 * @param instance
	 *            包含支持分页方法的对象的实例。
	 * @param name
	 *            支持的分页方法的在{@link PaginationMethod}中的名称。	
	 * @param otherParameters
	 *            除了偏移量,最大长度之外的参数值(按照原有的顺序排列)。
	 * @throws NullPointerException
	 *             如果instance为null,则抛出此异常。
	 * @throws MethodConfigurationException
	 *             PaginationMethod中参数配置错误或者在目标方法返回值既不是数组也不是{@link Collection}。
	 */
	public static  Pagination createPagination5(int page, int pageSize,
			int severalPagesNumber,Object instance, String name, 
			Object... otherParameters)
			throws NullPointerException, MethodConfigurationException {
		return createPagination(page, pageSize, 0, 
				severalPagesNumber,instance, name, otherParameters);
	}

	/**
	 * 创建分页导航,它通{@link #createPagination(int, int, int, int, Object, String, Object[])}
	 * 区别是:指定更多页中n值为{@link Pagination.DEFAULT_N}。
	 * @param page
	 *            页码,从1开始的整数值。
	 * @param pageSize
	 *            每页里面包含记录的最大条数。
	 * @param severalPagesNumber
	 *            上下n页的n值。
	 * @param instance
	 *            包含支持分页方法的对象的实例。
	 * @param name
	 *            支持的分页方法的在{@link PaginationMethod}中的名称。	
	 * @param otherParameters
	 *            除了偏移量,最大长度之外的参数值(按照原有的顺序排列)。
	 * @throws NullPointerException
	 *             如果instance为null,则抛出此异常。
	 * @throws MethodConfigurationException
	 *             PaginationMethod中参数配置错误或者在目标方法返回值既不是数组也不是{@link Collection}。
	 */
	public static  Pagination createPagination6(int page, int pageSize,
			int severalPagesNumber, Object instance,String name)
			throws NullPointerException, MethodConfigurationException {
		return createPagination(page, pageSize, 0, severalPagesNumber,
				instance, "");
	}
	
	/**
	 * 创建分页导航,它通{@link #createPagination(int, int, int, int, Object, String, Object[])}
	 * 区别是:指定“第一页开始记录的偏移量”为0的分页导航和指定更多页中n值为{@link Pagination.DEFAULT_N}。
	 * @param page
	 *            页码,从1开始的整数值。
	 * @param pageSize
	 *            每页里面包含记录的最大条数。
	 * @param offset
	 *            第一页开始记录的偏移量。
	 * @param severalPagesNumber
	 *            上下n页的n值。
	 * @param instance
	 *            包含支持分页方法的对象的实例。
	 * @param name
	 *            支持的分页方法的在{@link PaginationMethod}中的名称。	
	 * @param otherParameters
	 *            除了偏移量,最大长度之外的参数值(按照原有的顺序排列)。
	 * @throws NullPointerException
	 *             如果instance为null,则抛出此异常。
	 * @throws MethodConfigurationException
	 *             PaginationMethod中参数配置错误或者在目标方法返回值既不是数组也不是{@link Collection}。
	 */
	public static  Pagination createPagination7(int page, int pageSize,
			Object instance, String name,Object... otherParameters) throws NullPointerException,
			MethodConfigurationException {
		return createPagination(page, pageSize, 0, Pagination.DEFAULT_N,
				instance, name,otherParameters);
	}

	/**
	 * 创建分页导航,它通{@link #createPagination(int, int, int, int, Object, String, Object[])}
	 * 区别是:此方法用户于不包含otherParameters的分页导航,并且指定“第一页开始记录的偏移量”
	 * 为0和指定更多页中n值为{@link Pagination.DEFAULT_N}。
	 * @param page
	 *            页码,从1开始的整数值。
	 * @param pageSize
	 *            每页里面包含记录的最大条数。
	 * @param offset
	 *            第一页开始记录的偏移量。
	 * @param severalPagesNumber
	 *            上下n页的n值。
	 * @param instance
	 *            包含支持分页方法的对象的实例。
	 * @param name
	 *            支持的分页方法的在{@link PaginationMethod}中的名称。	
	 * @param otherParameters
	 *            除了偏移量,最大长度之外的参数值(按照原有的顺序排列)。
	 * @throws NullPointerException
	 *             如果instance为null,则抛出此异常。
	 * @throws MethodConfigurationException
	 *             PaginationMethod中参数配置错误或者在目标方法返回值既不是数组也不是
	 *             {@link Collection}。
	 */
	public static  Pagination createPagination8(int page, int pageSize,
			Object instance, String name) throws NullPointerException,
			MethodConfigurationException {
		return createPagination(page, pageSize, 0, Pagination.DEFAULT_N,
				instance, name);
	}

	
	/**
	 * 创建分页导航,它通{@link #createPagination(int, int, int, int, Object, String, Object[])}
	 * 区别是:此方法用户于不包含otherParameters的分页导航,并且指定“第一页开始记录的偏移量”
	 * 为0。
	 * @param page
	 *            页码,从1开始的整数值。
	 * @param pageSize
	 *            每页里面包含记录的最大条数。
	 * @param offset
	 *            第一页开始记录的偏移量。	
	 * @param instance
	 *            包含支持分页方法的对象的实例。
	 * @param name
	 *            支持的分页方法的在{@link PaginationMethod}中的名称。	
	 * @param otherParameters
	 *            除了偏移量,最大长度之外的参数值(按照原有的顺序排列)。	
	 * @throws NullPointerException
	 *             如果instance为null,则抛出此异常。
	 * @throws MethodConfigurationException
	 *             PaginationMethod中参数配置错误或者在目标方法返回值既不是数组也不是{@link Collection}。
	 */
	public static  Pagination createPagination9(int page, int pageSize,
			int offset, Object instance, String name, Object... otherParameters)
			throws NullPointerException, MethodConfigurationException {
		return createPagination(page, pageSize, offset, Pagination.DEFAULT_N,
				instance, name, otherParameters);
	}

}


5.MethodConfigurationException.java
package com.airinbox.pagination;

public class MethodConfigurationException extends Exception {

	private static final long serialVersionUID = -1568337814489507868L;

	public MethodConfigurationException() {
		super();		
	}

	public MethodConfigurationException(String message, Throwable cause) {
		super(message, cause);		
	}

	public MethodConfigurationException(String message) {
		super(message);		
	}

	public MethodConfigurationException(Throwable cause) {
		super(cause);		
	}

	
}



6.Example
public class Forum{
     @PaginationMethod(name = "ABC", offsetParamIndex = 1, maxLengthParamIndex = 2)
    public Article[] getArticleList(int forumId, int start, int len)
			throws ForumNotFoundException{
           ...
     }
}


7.Reference.jsp
      ....
      Forum forum = ...;
      Pagination pagi = PaginationFactory.createPagination8(1,10.forum,"ABC");
      Collection<?> c = pagi.getMethodReturnValue();//getArticleList返回的数据被包装到Collection里了
      for(Iterator<?> iter = c.iterator();ite.hasNext();){
           Article art = (Article)iter.next();
           ...
      }
      ...
分享到:
评论
2 楼 to2 2008-02-17  
谢谢,能否打包成完整的可以运行的rar提供下载。
1 楼 lsy 2007-01-11  
好文。能详细说明下使用么?

相关推荐

    hbase分页查询实现.pdf

    HBase分页查询实现 HBase作为一个NoSQL数据库,具有高性能、高可扩展性和高可靠性等特点,但是在查询方面却存在一些限制,例如不支持分页查询。这就使得开发者需要自己实现分页查询功能。本文将讲解如何使用Java...

    hbase分页查询实现[归类].pdf

    HBase分页查询实现 HBase是一种基于分布式的NoSQL数据库,它提供了高效的数据存储和检索能力。然而,HBase本身不支持分页查询,这使得开发者需要自己实现分页功能。本文将讲解如何使用Java语言实现HBase的分页查询...

    MyBatis Plus 的多表联接、分页查询实现方法,源码加sql

    MyBatis Plus 的多表联接、分页查询实现方法 http://localhost/common/getAllQuestionByPage/1/10 多表关联、分页查询接口 http://localhost/common/getAllQuestionWithStudentByPage/1/10 多表关联、分页带参数查询...

    Spring Data JPA带条件分页查询实现原理

    Spring Data JPA带条件分页查询实现原理 Spring Data JPA是Java持久化API(Java Persistence API)的一个实现,提供了一个简洁的方式来访问和操作数据库。在实际开发中,我们经常需要实现条件分页查询,以满足不同...

    Hibernate分页查询原理解读

    #### 三、Hibernate分页查询实现原理 ##### 3.1 使用SQL LIMIT实现分页 对于支持LIMIT关键字的数据库(例如MySQL),Hibernate会通过特定的方言(Dialect)来生成包含LIMIT关键字的SQL语句。具体实现如下: ```...

    hibernate实现分页查询

    #### 三、Hibernate 分页查询实现步骤 ##### 3.1 创建Session实例 在Hibernate中,所有的持久化操作都需要在一个`Session`实例的控制下进行。因此,第一步是打开一个`Session`实例。 ```java Session session = ...

    分页显示实现过程.docx

    在这个实现过程中,我们将讲解如何定义变量、计算页数、实现分页查询和显示结果。 一、定义变量 在实现分页显示时,我们需要定义四个变量: 1. pageSize:定义一页显示多少条记录。 2. pageNow:定义当前显示第几...

    jdbc+serlvet分页查询代码

    **分页查询实现** 在实际的分页查询中,通常需要维护页码和每页记录数。Servlet可以接收这两个参数,通过HTTP请求传递给后端的JDBC代码。分页查询的实现步骤可能包括: 1. **计算偏移量**:根据当前页码和每页记录...

    基于springmvc实现分页查询

    本篇文章将详细探讨如何基于Spring MVC实现分页查询,这对于任何处理大量数据的Web应用都是至关重要的。 首先,理解分页的基本概念。分页是将大型数据集划分为较小、更易管理的部分,以提高用户体验并减少服务器...

    基于SSH架构的分页查询标签的研究与实现

    然而,传统的分页查询实现方式往往存在代码冗余、可维护性差等问题。本文介绍了一种基于SSH(Struts + Spring + Hibernate)架构的分页查询解决方案,通过利用JSP自定义标签技术和Hibernate Query Language (HQL),...

    java自定义分页标签实现带条件的分页查询

    本话题主要探讨如何使用自定义的Java分页标签来实现带条件的分页查询,这将帮助开发者更好地控制和优化数据检索。 首先,我们需要了解分页的基本原理。分页查询是通过限制数据库查询返回的结果数量,每次只获取一...

    使用JSP实现查询分页

    4. **分页查询**:使用`ResultSet rs = test.query("select * from student");`执行查询,并利用`absolute`方法定位到当前页的第一条记录。 5. **展示数据**:通过循环遍历`ResultSet`,将数据展示在`&lt;tr&gt;`和`&lt;td&gt;`...

    SQLite 查询所有 分页查询 查询个数

    在处理大量数据时,为了提高效率并避免一次性加载所有数据导致性能下降,通常会采用分页查询的方式来获取数据。下面我们将详细探讨SQLite中的查询所有、分页查询以及查询个数的相关知识点。 1. 查询所有数据: 在...

    实现分页查询(上)

    本篇文章将深入探讨分页查询的概念、实现原理以及常见方法,以帮助开发者构建更加高效、用户友好的应用程序。 一、分页查询的概念 分页查询是指在处理大量数据时,将其分为多个小块(页),每次只加载一部分数据到...

    JavaWeb实现分页查询案例

    本案例通过原生的PageBean实现分页查询,采用JDBC(Java Database Connectivity)进行数据库操作,Servlet作为控制层处理请求,JSP(JavaServer Pages)用于展示数据。以下将详细解释这个案例中的关键知识点。 首先...

    Struts2实现分页查询

    用Struts2+mysql实现的简单信息录入,分页查询

    使用MybatisPlus+SpringMBVC完成的CUID以及分页查询实现Demo

    使用MyBatisPlus的逆向工程自动生成Mapper接口,xml文件,service接口,service实现以及controller并整合Spring框架完成单表CUID和分页操作,代码讲解请参看:...

    mybatis分页查询例子 idea实现

    在这个过程中,PageHelper会自动拦截SQL语句,添加上分页的相关条件,从而实现分页查询。此外,PageInfo对象包含了当前页的数据列表、总页数、总记录数等信息,方便我们在前端展示分页效果。 为了更好地理解这个...

Global site tag (gtag.js) - Google Analytics