📄 largeselect.java
字号:
* limits (when available), the provided criteria must not have any limit or * offset defined. If the criteria does not include the definition of any * select columns the <code>addSelectColumns(Criteria)</code> method of * the class named as <code>returnBuilderClassName</code> will be used to * add them. * @param pageSize number of rows to return in one block. * @param returnBuilderClassName The name of the class that will be used to * build the result records (may implement <code>addSelectColumns(Criteria) * </code> and must implement <code>populateObjects(List)</code>). * @throws IllegalArgumentException if <code>criteria</code> uses one or * both of offset and limit, if <code>pageSize</code> is less than 1, or if * problems are experienced locating and invoking either one or both of * <code>addSelectColumns(Criteria)</code> and <code> populateObjects(List) * </code> in the class named <code>returnBuilderClassName</code>. */ public LargeSelect( Criteria criteria, int pageSize, String returnBuilderClassName) throws IllegalArgumentException { this( criteria, pageSize, LargeSelect.memoryPageLimit, returnBuilderClassName); } /** * Creates a LargeSelect whose results are returned as a <code>List</code> * containing a maximum of <code>pageSize</code> objects of the type * defined within the class named <code>returnBuilderClassName</code> at a * time, maintaining a maximum of <code>memoryPageLimit</code> pages of * results in memory. * * @param criteria object used by BasePeer to build the query. In order to * allow this class to utilise database server implemented offsets and * limits (when available), the provided criteria must not have any limit or * offset defined. If the criteria does not include the definition of any * select columns the <code>addSelectColumns(Criteria)</code> method of * the class named as <code>returnBuilderClassName</code> will be used to * add them. * @param pageSize number of rows to return in one block. * @param memoryPageLimit maximum number of pages worth of rows to be held * in memory at one time. * @param returnBuilderClassName The name of the class that will be used to * build the result records (may implement <code>addSelectColumns(Criteria) * </code> and must implement <code>populateObjects(List)</code>). * @throws IllegalArgumentException if <code>criteria</code> uses one or * both of offset and limit, if <code>pageSize</code> or <code> * memoryLimitPages</code> are less than 1, or if problems are experienced * locating and invoking either one or both of <code> * addSelectColumns(Criteria)</code> and <code> populateObjects(List)</code> * in the class named <code>returnBuilderClassName</code>. */ public LargeSelect( Criteria criteria, int pageSize, int memoryPageLimit, String returnBuilderClassName) throws IllegalArgumentException { try { this.returnBuilderClass = Class.forName(returnBuilderClassName); // Add the select columns if necessary. if (criteria.getSelectColumns().size() == 0) { Class[] argTypes = { Criteria.class }; Method selectColumnAdder = returnBuilderClass.getMethod("addSelectColumns", argTypes); Object[] theArgs = { criteria }; selectColumnAdder.invoke(returnBuilderClass.newInstance(), theArgs); } // Locate the populateObjects() method - this will be used later Class[] argTypes = { List.class }; populateObjectsMethod = returnBuilderClass.getMethod("populateObjects", argTypes); } catch (Exception e) { throw new IllegalArgumentException( "The class named as returnBuilderClassName does not " + "provide the necessary facilities - see javadoc."); } init(criteria, pageSize, memoryPageLimit); } /** * Called by the constructors to start the query. * * @param criteria Object used by <code>BasePeer</code> to build the query. * In order to allow this class to utilise database server implemented * offsets and limits (when available), the provided criteria must not have * any limit or offset defined. * @param pageSize number of rows to return in one block. * @param memoryLimitPages maximum number of pages worth of rows to be held * in memory at one time. * @throws IllegalArgumentException if <code>criteria</code> uses one or * both of offset and limit and if <code>pageSize</code> or * <code>memoryLimitPages</code> are less than 1; */ private void init(Criteria criteria, int pageSize, int memoryLimitPages) throws IllegalArgumentException { if (criteria.getOffset() != 0 || criteria.getLimit() != -1) { throw new IllegalArgumentException( "criteria must not use Offset and/or Limit."); } if (pageSize < 1) { throw new IllegalArgumentException( "pageSize must be greater than zero."); } if (memoryLimitPages < 1) { throw new IllegalArgumentException( "memoryPageLimit must be greater than zero."); } this.pageSize = pageSize; this.memoryLimit = pageSize * memoryLimitPages; this.criteria = criteria; dbName = criteria.getDbName(); blockEnd = blockBegin + memoryLimit - 1; startQuery(pageSize); } /** * Retrieve a specific page, if it exists. * * @param pageNumber the number of the page to be retrieved - must be * greater than zero. An empty <code>List</code> will be returned if * <code>pageNumber</code> exceeds the total number of pages that exist. * @return a <code>List</code> of query results containing a maximum of * <code>pageSize</code> results. * @throws IllegalArgumentException when <code>pageNo</code> is not * greater than zero. * @throws TorqueException if invoking the <code>populateObjects()<code> * method runs into problems or a sleep is unexpectedly interrupted. */ public List getPage(int pageNumber) throws TorqueException { if (pageNumber < 1) { throw new IllegalArgumentException("pageNumber must be greater " + "than zero."); } currentPageNumber = pageNumber; return getResults((pageNumber - 1) * pageSize); } /** * Gets the next page of rows. * * @return a <code>List</code> of query results containing a maximum of * <code>pageSize</code> reslts. * @throws TorqueException if invoking the <code>populateObjects()<code> * method runs into problems or a sleep is unexpectedly interrupted. */ public List getNextResults() throws TorqueException { if (!getNextResultsAvailable()) { return getCurrentPageResults(); } currentPageNumber++; return getResults(position); } /** * Provide access to the results from the current page. * * @return a <code>List</code> of query results containing a maximum of * <code>pageSize</code> reslts. */ public List getCurrentPageResults() { return lastResults; } /** * Gets the previous page of rows. * * @return a <code>List</code> of query results containing a maximum of * <code>pageSize</code> reslts. * @throws TorqueException if invoking the <code>populateObjects()<code> * method runs into problems or a sleep is unexpectedly interrupted. */ public List getPreviousResults() throws TorqueException { if (!getPreviousResultsAvailable()) { return getCurrentPageResults(); } int start; if (position - 2 * pageSize < 0) { start = 0; currentPageNumber = 1; } else { start = position - 2 * pageSize; currentPageNumber--; } return getResults(start); } /** * Gets a page of rows starting at a specified row. * * @param start the starting row. * @return a <code>List</code> of query results containing a maximum of * <code>pageSize</code> reslts. * @throws TorqueException if invoking the <code>populateObjects()<code> * method runs into problems or a sleep is unexpectedly interrupted. */ private List getResults(int start) throws TorqueException { return getResults(start, pageSize); } /** * Gets a block of rows starting at a specified row and containing a * specified number of rows. * * @param start the starting row. * @param size the number of rows. * @return a <code>List</code> of query results containing a maximum of * <code>pageSize</code> reslts. * @throws IllegalArgumentException if <code>size > memoryLimit</code> or * <code>start</code> and <code>size</code> result in a situation that is * not catered for. * @throws TorqueException if invoking the <code>populateObjects()<code> * method runs into problems or a sleep is unexpectedly interrupted. */ private synchronized List getResults(int start, int size) throws IllegalArgumentException, TorqueException { if (log.isDebugEnabled()) { log.debug("getResults(start: " + start + ", size: " + size + ") invoked."); } if (size > memoryLimit) { throw new IllegalArgumentException("size (" + size + ") exceeds memory limit (" + memoryLimit + ")."); } // Request was for a block of rows which should be in progess. // If the rows have not yet been returned, wait for them to be // retrieved. if (start >= blockBegin && (start + size - 1) <= blockEnd) { if (log.isDebugEnabled()) { log.debug("getResults(): Sleeping until " + "start+size-1 (" + (start + size - 1) + ") > currentlyFilledTo (" + currentlyFilledTo + ") && !queryCompleted (!" + queryCompleted + ")"); } while (((start + size - 1) > currentlyFilledTo) && !queryCompleted) { try { Thread.sleep(500); } catch (InterruptedException e) { throw new TorqueException("Unexpected interruption", e); } } } // Going in reverse direction, trying to limit db hits so assume user // might want at least 2 sets of data. else if (start < blockBegin && start >= 0) { if (log.isDebugEnabled()) { log.debug("getResults(): Paging backwards as start (" + start + ") < blockBegin (" + blockBegin + ") && start >= 0"); } stopQuery(); if (memoryLimit >= 2 * size) { blockBegin = start - size; if (blockBegin < 0) { blockBegin = 0; } } else { blockBegin = start; } blockEnd = blockBegin + memoryLimit - 1; startQuery(size); // Re-invoke getResults() to provide the wait processing. return getResults(start, size); } // Assume we are moving on, do not retrieve any records prior to start. else if ((start + size - 1) > blockEnd) { if (log.isDebugEnabled()) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -