Result sets need not be "regular" in shape. A result set can be as simple as one member that is a single text or numeric value. Or a result set can have several members, including one or more members that are lists or arrays. All members are created using one of two variations of the add() method:To add a simple (scalar) member to a result set, use the variation of the add() method with the rsMember parameter. For example:
rset.add("announcement", new TextData("Hello World!"));
To add a complex (list type) member to a result set, use the variation of the Add method with the listName parameter.
Simple stub interface for a set of results to a select query. This is considered to be an {@link Iterator} set of {@link BindingSet} objects. BindingSet objects are map-like structures where the keysare the names elements of the projection of the query and the values are the bindings for that particular query solution.
Even though this implements Iterator, it is not expected for the remove method to have any result on the result set, or on the DataSource the results came from, the most likely implementation of the method is a no-op
@author Michael Grove @since 0.1 @version 0.7The retrieval of the rows of a ResultSet is generally paged (a first page of result is fetched and the next one is only fetched once all the results of the first one has been consumed). The size of the pages can be configured either globally through {@link QueryOptions#setFetchSize} or per-statementwith {@link Statement#setFetchSize}. Though new pages are automatically (and transparently) fetched when needed, it is possible to force the retrieval of the next page early through {@link #fetchMoreResults}. Please note however that this ResultSet paging is not available with the version 1 of the native protocol (i.e. with Cassandra 1.2 or if version 1 has been explicitly requested through {@link Cluster.Builder#withProtocolVersion}). If the protocol version 1 is in use, a ResultSet is always fetched in it's entirely and it's up to the client to make sure that no query can yield ResultSet that won't hold in memory.
Note that this class is not thread-safe.
ResultSet
must have its {@link #close()} called once it is nolonger needed. The {@link ResultSet} class provides methods for getting fields as aparticular type, getFieldAdByte
, getFieldAdChar
, etc. These getter methods will attempt to convert the field value into the requested type, but the overflow behavior is undefined.
ResultSet
must have its {@link #close()} called once it is nolonger needed.
A ResultSet maintains a cursor pointing to its current row of data. Initially the cursor is positioned before the first row. The 'next' method moves the cursor to the next row.
The getXXX methods retrieve column values for the current row. You can retrieve values either using the index number of the column, or by using the name of the column. In general using the column index will be more efficient. Columns are numbered from 1.
For maximum portability, ResultSet columns within each row should be read in left-to-right order and each column should be read only once.
For the getXXX methods, the JDBC driver attempts to convert the underlying data to the specified Java type and returns a suitable Java value. See the JDBC specification for allowable mappings from SQL types to Java types with the ResultSet getXXX methods.
Column names used as input to getXXX methods are case insenstive. When performing a getXXX using a column name, if several columns have the same name, then the value of the first matching column will be returned. The column name option is designed to be used when column names are used in the SQL Query. For columns that are NOT explicitly named in the query, it is best to use column numbers. If column names were used there is no way for the programmer to guarentee that they actually refer to the intended columns.
A ResultSet is automatically closed by the Statement that generated it when that Statement is closed, re-executed, or is used to retrieve the next result from a sequence of multiple results.
The number, types and properties of a ResultSet's columns are provided by the ResultSetMetaData object returned by the getMetaData method.
@author Mark Matthews @version $Id: ResultSet.java 20 2008-01-17 12:47:41Z gnovelli $ @see ResultSetMetaData @see java.sql.ResultSetResultSets manage data paging, that is, loading records in batches as the user navigates the data set. A ResultSet will switch to using client-side sorting and filtering when possible to improve responsiveness and reduce server load. ResultSets also participate in automatic cache synchronization, observing operations on DataSources and automatically updating their caches.
Creation
A ResultSet can be passed to any component that expects a List, and the List APIs can be called directly on the ResultSet as long as the caller is able to deal with asynchronous loading; see {@link ResultSet#getRange}.
Generally ResultSets do not need to be created directly, but are created by DataBound
components as an automatic consequence of calling
{@link com.smartgwt.client.docs.DataBoundComponentMethods 'DataBound Component Methods'}.
For example, the {@link com.smartgwt.client.widgets.grid.ListGrid#fetchData} causes {@link com.smartgwt.client.widgets.grid.ListGrid#getData data} to become an
automatically created ResultSet
object. Automatically created ResultSets
canbe customized via properties on ListGrids such as {@link com.smartgwt.client.widgets.grid.ListGrid#getDataPageSize dataPageSize} and
{@link com.smartgwt.client.widgets.grid.ListGrid#getDataProperties dataProperties}. All ResultSets for a given DataSource may also be
customized via setting {@link DataSource#getResultSetClass resultSetClass} to the name of a ResultSet
{@link com.smartgwt.client.util.isc#defineClass} in which
{@link com.smartgwt.client..Class#addProperties}.
A ResultSet defaults to using data paging, setting {@link DSRequest#getStartRow startRow}and {@link DSRequest#getEndRow endRow} in issued dsRequests. Server code may alwaysreturn more rows than the ResultSet requests and the ResultSet will correctly integrate those rows based on {@link DSResponse#getStartRow startRow}/ {@link DSResponse#getEndRow'endRow'}. Hence the server can always avoid paging mode by simply returning all matching rows.
A ResultSet can be created directly with just the ID of a {@link DataSource}:
isc.ResultSet.create({ dataSource : "dataSourceID" })
Directly created ResultSets are typically used by custom components, or as a means of managing datasets that will be used by several components.
When created directly rather than via a dataBoundComponent, a newly created ResultSet will not issue it's first "fetch" {@link DSRequest} until data is accessed (for example,via {@link ResultSet#get}).
Paging and total dataset length
When using data paging, the server communicates the total number of records that match the current search criteria by setting {@link DSResponse#getTotalRows totalRows}. The ResultSet will then return this number from {@link ResultSet#getLength}, and ListGrids and other components will show a scrollbar that allows the user to jump to the end of the dataset directly.
However, the ResultSet does not require that the server calculate the true length of the
dataset, which can be costly for an extremely large, searchable dataset. Instead, the
server may simply advertise a totalRows
value that is one page larger
than the last row loaded. This results in a UI sometimes called "progressive loading",
where the user may load more rows by scrolling past the end of the currently loaded rows,
but is not allowed to skip to the end of the dataset.
No client-side settings are required to enable this mode - it is entirely server-driven. However, it is usually coupled with {@link com.smartgwt.client.widgets.grid.ListGrid#getCanSort 'disabling sorting'}, since server-side sorting would also force the server to traverse the entire dataset.
Client-side Sorting and Filtering
If a ResultSet obtains a full cache for the current set of filter criteria, it will automatically switch to client-side sorting, and will also use client-side filtering if the filter criteria are later changed but appear to be more restrictive than the criteria in use when the ResultSet obtained a full cache.
The {@link ResultSet#getUseClientSorting 'useClientSorting'} and {@link ResultSet#getUseClientFiltering 'useClientFiltering'} flags can be used to disable client-side sorting and filtering respectively if these behaviors don't match server-based sorting and filtering. However, because client-side sorting and filtering radically improve responsiveness and reduce server load, it is better to customize the ResultSet so that it can match server-side sorting and filtering behaviors.
Sorting behavior is primarily customized via the "sort normalizer" passed to {@link ResultSet#sortByProperty}, either via direct calls on a standalone ResultSet, or via {@link com.smartgwt.client.widgets.grid.ListGridField#sortNormalizer} for a ListGrid-managed ResultSet.
Bydefault, client-side filtering interprets the {@link Criteria} passed to {@link ResultSet#setCriteria} as a set of field values that records must match (similarly to thebuilt-in SQL/Hibernate connectors built into the SmartGWT Server). Custom client-side filtering logic can be implemented by overriding {@link ResultSet#applyFilter}. Overriding {@link ResultSet#compareCriteria} allows you to control when the ResultSet uses client-side vsserver-side filtering, and the ResultSet has two default {@link ResultSet#getCriteriaPolicy 'criteria policies'} built-in.
Updates andAutomatic Cache Synchronization
ResultSets observe any successful "update", "add" or "remove" dsRequests against their DataSource, regardless of the component that initiated them. A ResultSet with a full cache for the current filter criteria will integrate updates into the cache automatically.
Updated rows that no longer match the current filter criteria will be removed automatically. To prevent this, you can set {@link ResultSet#getNeverDropUpdatedRows neverDropUpdatedRows}. Added rows will similarly be added to the cache only if they match current filter criteria.
Note that the client-side filtering described above is also used to determine whether updated or added rows should be in the cache. If any aspect of automated cache update is ever incorrect, {@link ResultSet#getDropCacheOnUpdate'dropCacheOnUpdate'} can be set for the ResultSet or {@link DSResponse#getInvalidateCache invalidateCache} can be set for an individual dsResponse.
Data Paging with partial cache
When in paging mode with a partial cache, a ResultSet relies on server side sorting, setting {@link DSRequest#getSortBy sortBy} to the current sort field and direction. In order for the cache to remain coherant, row numbering must continue to agree between server and client as new fetches are issued, otherwise, duplicate rows or missing rows may occur.
If concurrent modifications by other users are allowed, generally the server should set {@link DSResponse#getInvalidateCache invalidateCache} to clear the cache when concurrent modification is detected.
In paging mode with apartial cache, any successful "update" or "add" operation may cause client and server row numbering to become out of sync. This happens because the update may affect the sort order, and client and server cannot be guaranteed to match for sets of records that have equivalent values for the sort field.
For this reason, after an "add" or "update" operation with a partial cache, the ResultSet will automatically mark cache for invalidation the next time a fetch operation is performed. Alternatively, if {@link ResultSet#getUpdatePartialCache updatePartialCache} is set to false, the ResultSet will simply invalidate cache immediately in this circumstance.
The ResultSet interface provides a series of methods for retrieving data from columns in the current row, such as getDate, getFloat. The columns are identified either by their index number (starting at 1) or by their name - there are separate methods for both techniques of column addressing. The column names are case insensitive. If several columns have the same name, then the getter methods use the first matching column. This means that if column names are used, it is not possible to guarantee that the name will retrieve data from the intended column - for certainty it is better to use column indexes. Ideally the columns should be read left-to-right and read once only, since not all * databases are optimised to handle other techniques of reading the data.
When reading data, the JDBC driver maps the SQL data retrieved from the database to the Java type implied by the method invoked by the application. The JDBC specification has a table of allowable mappings from SQL types to Java types.
There are also methods for writing data into the ResultSet, such as updateInt, updateString. The update methods can be used either to modify the data of an existing row or to insert new data rows into the ResultSet. Modification of existing data involves moving the Cursor to the row which needs modification and then using the update methods to modify the data, followed by calling the ResultSet.updateRow method. For insertion of new rows, the cursor is first moved to a special row called the Insert Row, data is added using the update methods, followed by calling the ResultSet.insertRow method.
A ResultSet is closed if the Statement object which generated it closed, executed again or is used to retrieve the next result from a sequence of results.
There is no single implementation of the ResultSet interface. Instead, the various support operations involved in executing statements implement this interface.
Although ExecRow is used on the interface, it is not available to users of the API. They should use Row, the exposed super-interface of ExecRow. <>
Valid transitions:
The ResultSet can also be used in conjunction with the MessageManager class that provide Locale independent messaging. The ResultSet has an associated Locale that users of the class can use to generate the appropriate messages dependent on the Locale. @author Peter Strong @version 1.0
In addition to the methods inherited from the java.util.Iterator
interface, it defines an extra method to explicitly free any buffers bound to the iterator. Applications that use prefix or range queries should invoke free()
once the result set is no longer needed, so as to keep the memory footprint of BabuDB as low as possible.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|