⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 largeselect.java

📁 torque服务器源代码
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
package org.apache.torque.util;/* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. * * 3. The end-user documentation included with the redistribution, *    if any, must include the following acknowledgment: *       "This product includes software developed by the *        Apache Software Foundation (http://www.apache.org/)." *    Alternately, this acknowledgment may appear in the software itself, *    if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" and *    "Apache Turbine" must not be used to endorse or promote products *    derived from this software without prior written permission. For *    written permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", *    "Apache Turbine", nor may "Apache" appear in their name, without *    prior written permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation.  For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */import java.sql.Connection;import java.sql.SQLException;import java.util.Iterator;import java.util.List;import java.util.ArrayList;import java.util.Hashtable;import java.util.Set;import java.io.Serializable;import java.lang.reflect.Method;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.apache.torque.Torque;import org.apache.torque.TorqueException;import com.workingdogs.village.QueryDataSet;import com.workingdogs.village.DataSetException;/** * This class can be used to retrieve a large result set from a database query. * The query is started and then rows are returned a page at a time.  The <code> * LargeSelect</code> is meant to be placed into the Session or User.Temp, so * that it can be used in response to several related requests.  Note that in * order to use <code>LargeSelect</code> you need to be willing to accept the * fact that the result set may become inconsistent with the database if updates * are processed subsequent to the queries being executed.  Specifying a memory * page limit of 1 will give you a consistent view of the records but the totals * may not be accurate and the performance will be terrible.  In most cases * the potential for inconsistencies data should not cause any serious problems * and performance should be pretty good (but read on for further warnings). * * <p>The idea here is that the full query result would consume too much memory * and if displayed to a user the page would be too long to be useful.  Rather * than loading the full result set into memory, a window of data (the memory * limit) is loaded and retrieved a page at a time.  If a request occurs for * data that falls outside the currently loaded window of data then a new query * is executed to fetch the required data.  Performance is optimized by * starting a thread to execute the database query and fetch the results.  This * will perform best when paging forwards through the data, but a minor * optimization where the window is moved backwards by two rather than one page * is included for when a user pages past the beginning of the window. * * <p>As the query is performed in in steps, it is often the case that the total * number of records and pages of data is unknown.  <code>LargeSelect</code> * provides various methods for indicating how many records and pages it is * currently aware of and for presenting this information to users. * * <p><code>LargeSelect</code> utilises the <code>Criteria</code> methods * <code>setOffset()</code> and <code>setLimit()</code> to limit the amount of * data retrieved from the database - these values are either passed through to * the DBMS when supported (efficient with the caveat below) or handled by * the Village API when it is not (not so efficient).  At time of writing * <code>Criteria</code> will only pass the offset and limit through to MySQL * and PostgreSQL (with a few changes to <code>DBOracle</code> and <code> * BasePeer</code> Oracle support can be implemented by utilising the <code> * rownum</code> pseudo column). * * <p>As <code>LargeSelect</code> must re-execute the query each time the user * pages out of the window of loaded data, you should consider the impact of * non-index sort orderings and other criteria that will require the DBMS to * execute the entire query before filtering down to the offset and limit either * internally or via Village. * * <p>The memory limit defaults to 5 times the page size you specify, but * alternative constructors and the class method <code>setMemoryPageLimit() * </code> allow you to override this for a specific instance of * <code>LargeSelect</code> or future instances respectively. * * <p>Some of the constructors allow you to specify the name of the class to use * to build the returnd rows.  This works by using reflection to find <code> * addSelectColumns(Criteria)</code> and <code>populateObjects(List)</code> * methods to add the necessary select columns to the criteria (only if it * doesn't already contain any) and to convert query results from Village * <code>Record</code> objects to a class defined within the builder class. * This allows you to use any of the Torque generated Peer classes, but also * makes it fairly simple to construct business object classes that can be used * for this purpose (simply copy and customise the <code>addSelectColumns() * </code>, <code>populateObjects()</code>, <code>row2Object()</code> and <code> * populateObject()</code> methods from an existing Peer class). * * <p>Typically you will create a <code>LargeSelect</code> using your <code> * Criteria</code> (perhaps created from the results of a search parameter * page), page size, memory page limit and return class name (for which you may * have defined a business object class before hand) and place this in user.Temp * thus: * * <pre> *     data.getUser().setTemp("someName", largeSelect); * </pre> * * <p>In your template you will then use something along the lines of: * * <pre> *    #set ($largeSelect = $data.User.getTemp("someName")) *    #set ($searchop = $data.Parameters.getString("searchop")) *    #if ($searchop.equals("prev")) *      #set ($recs = $largeSelect.PreviousResults) *    #else *      #if ($searchop.equals("goto")) *        #set ($recs *                = $largeSelect.getPage($data.Parameters.getInt("page", 1))) *      #else *        #set ($recs = $largeSelect.NextResults) *      #end *    #end * </pre> * * <p>...to move through the records.  <code>LargeSelect</code> implements a * number of convenience methods that make it easy to add all of the necessary * bells and whistles to your template. * * @author <a href="mailto:john.mcnally@clearink.com">John D. McNally</a> * @author <a href="mailto:seade@backstagetech.com.au">Scott Eade</a> * @version $Id: LargeSelect.java,v 1.13 2003/08/25 16:33:23 henning Exp $ */public class LargeSelect implements Runnable, Serializable{    /** The number of records that a page consists of.  */    private int pageSize;    /** The maximum number of records to maintain in memory. */    private int memoryLimit;    /** The record number of the first record in memory. */    private int blockBegin = 0;    /** The record number of the last record in memory. */    private int blockEnd;    /** How much of the memory block is currently occupied with result data. */    private volatile int currentlyFilledTo = -1;    /** The SQL query that this <code>LargeSelect</code> represents. */    private String query;    /** The database name to get from Torque. */    private String dbName;    /** Used to retrieve query results from Village. */    private QueryDataSet qds = null;    /** The memory store of records. */    private List results = null;    /** The thread that executes the query. */    private Thread thread = null;    /**     * A flag used to kill the thread when the currently executing query is no     * longer required.     */    private volatile boolean killThread = false;    /** A flag that indicates whether or not the query thread is running. */    private volatile boolean threadRunning = false;    /**     * An indication of whether or not the current query has completed     * processing.     */    private volatile boolean queryCompleted = false;    /**     * An indication of whether or not the totals (records and pages) are at     * their final values.     */    private boolean totalsFinalized = false;    /** The cursor position in the result set. */    private int position;    /** The total number of pages known to exist. */    private int totalPages = -1;    /** The total number of records known to exist. */    private int totalRecords = 0;    /** The number of the page that was last retrieved. */    private int currentPageNumber = 0;    /** The criteria used for the query. */    private Criteria criteria = null;    /** The last page of results that were returned. */    private List lastResults;    /**     * The class that is possibly used to construct the criteria and used     * to transform the Village Records into the desired OM or business objects.     */    private Class returnBuilderClass = null;    /**     * A reference to the method in the return builder class that will     * convert the Village Records to the desired class.     */    private Method populateObjectsMethod = null;    /**     * The default value ("&gt;") used to indicate that the total number of     * records or pages is unknown. You can use <code>setMoreIndicator()</code>     * to change this to whatever value you like (e.g. "more than").     */    public static final String DEFAULT_MORE_INDICATOR = "&gt;";    private static String moreIndicator = DEFAULT_MORE_INDICATOR;    /**     * The default value for the maximum number of pages of data to be retained     * in memory - you can provide your own default value using     * <code>setMemoryPageLimit()</code>.     */    public static final int DEFAULT_MEMORY_LIMIT_PAGES = 5;    private static int memoryPageLimit = DEFAULT_MEMORY_LIMIT_PAGES;    /** A place to store search parameters that relate to this query. */    private Hashtable params = null;    /** Logging */    private static Log log = LogFactory.getLog(LargeSelect.class);    /**     * Creates a LargeSelect whose results are returned as a <code>List</code>     * containing a maximum of <code>pageSize</code> Village <code>Record</code>     * objects at a time, maintaining a maximum of     * <code>LargeSelect.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.     * @param pageSize number of rows to return in one block.     * @throws IllegalArgumentException if <code>criteria</code> uses one or     * both of offset and limit, or if <code>pageSize</code> is less than 1;     */    public LargeSelect(Criteria criteria, int pageSize)            throws IllegalArgumentException    {        this(criteria, pageSize, LargeSelect.memoryPageLimit);    }    /**     * Creates a LargeSelect whose results are returned as a <code>List</code>     * containing a maximum of <code>pageSize</code> Village <code>Record</code>     * objects 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.     * @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.     * @throws IllegalArgumentException if <code>criteria</code> uses one or     * both of offset and limit, or if <code>pageSize</code> or     * <code>memoryLimitPages</code> are less than 1;     */    public LargeSelect(Criteria criteria, int pageSize, int memoryPageLimit)            throws IllegalArgumentException    {        init(criteria, pageSize, memoryPageLimit);    }    /**     * 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>LargeSelect.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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -