同步操作将从 Stefan/Java8Source 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
/** Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.*********************/package javax.sql.rowset;import java.sql.*;import javax.sql.*;import javax.naming.*;import java.io.*;import java.math.*;import java.util.*;import javax.sql.rowset.spi.*;/*** The interface that all standard implementations of* <code>CachedRowSet</code> must implement.* <P>* The reference implementation of the <code>CachedRowSet</code> interface provided* by Oracle Corporation is a standard implementation. Developers may use this implementation* just as it is, they may extend it, or they may choose to write their own implementations* of this interface.* <P>* A <code>CachedRowSet</code> object is a container for rows of data* that caches its rows in memory, which makes it possible to operate without always being* connected to its data source. Further, it is a* JavaBeans™ component and is scrollable,* updatable, and serializable. A <code>CachedRowSet</code> object typically* contains rows from a result set, but it can also contain rows from any file* with a tabular format, such as a spread sheet. The reference implementation* supports getting data only from a <code>ResultSet</code> object, but* developers can extend the <code>SyncProvider</code> implementations to provide* access to other tabular data sources.* <P>* An application can modify the data in a <code>CachedRowSet</code> object, and* those modifications can then be propagated back to the source of the data.* <P>* A <code>CachedRowSet</code> object is a <i>disconnected</i> rowset, which means* that it makes use of a connection to its data source only briefly. It connects to its* data source while it is reading data to populate itself with rows and again* while it is propagating changes back to its underlying data source. The rest* of the time, a <code>CachedRowSet</code> object is disconnected, including* while its data is being modified. Being disconnected makes a <code>RowSet</code>* object much leaner and therefore much easier to pass to another component. For* example, a disconnected <code>RowSet</code> object can be serialized and passed* over the wire to a thin client such as a personal digital assistant (PDA).*** <h3>1.0 Creating a <code>CachedRowSet</code> Object</h3>* The following line of code uses the default constructor for* <code>CachedRowSet</code>* supplied in the reference implementation (RI) to create a default* <code>CachedRowSet</code> object.* <PRE>* CachedRowSetImpl crs = new CachedRowSetImpl();* </PRE>* This new <code>CachedRowSet</code> object will have its properties set to the* default properties of a <code>BaseRowSet</code> object, and, in addition, it will* have an <code>RIOptimisticProvider</code> object as its synchronization provider.* <code>RIOptimisticProvider</code>, one of two <code>SyncProvider</code>* implementations included in the RI, is the default provider that the* <code>SyncFactory</code> singleton will supply when no synchronization* provider is specified.* <P>* A <code>SyncProvider</code> object provides a <code>CachedRowSet</code> object* with a reader (a <code>RowSetReader</code> object) for reading data from a* data source to populate itself with data. A reader can be implemented to read* data from a <code>ResultSet</code> object or from a file with a tabular format.* A <code>SyncProvider</code> object also provides* a writer (a <code>RowSetWriter</code> object) for synchronizing any* modifications to the <code>CachedRowSet</code> object's data made while it was* disconnected with the data in the underlying data source.* <P>* A writer can be implemented to exercise various degrees of care in checking* for conflicts and in avoiding them.* (A conflict occurs when a value in the data source has been changed after* the rowset populated itself with that value.)* The <code>RIOptimisticProvider</code> implementation assumes there will be* few or no conflicts and therefore sets no locks. It updates the data source* with values from the <code>CachedRowSet</code> object only if there are no* conflicts.* Other writers can be implemented so that they always write modified data to* the data source, which can be accomplished either by not checking for conflicts* or, on the other end of the spectrum, by setting locks sufficient to prevent data* in the data source from being changed. Still other writer implementations can be* somewhere in between.* <P>* A <code>CachedRowSet</code> object may use any* <code>SyncProvider</code> implementation that has been registered* with the <code>SyncFactory</code> singleton. An application* can find out which <code>SyncProvider</code> implementations have been* registered by calling the following line of code.* <PRE>* java.util.Enumeration providers = SyncFactory.getRegisteredProviders();* </PRE>* <P>* There are two ways for a <code>CachedRowSet</code> object to specify which* <code>SyncProvider</code> object it will use.* <UL>* <LI>Supplying the name of the implementation to the constructor<BR>* The following line of code creates the <code>CachedRowSet</code>* object <i>crs2</i> that is initialized with default values except that its* <code>SyncProvider</code> object is the one specified.* <PRE>* CachedRowSetImpl crs2 = new CachedRowSetImpl(* "com.fred.providers.HighAvailabilityProvider");* </PRE>* <LI>Setting the <code>SyncProvider</code> using the <code>CachedRowSet</code>* method <code>setSyncProvider</code><BR>* The following line of code resets the <code>SyncProvider</code> object* for <i>crs</i>, the <code>CachedRowSet</code> object created with the* default constructor.* <PRE>* crs.setSyncProvider("com.fred.providers.HighAvailabilityProvider");* </PRE>* </UL>* See the comments for <code>SyncFactory</code> and <code>SyncProvider</code> for* more details.*** <h3>2.0 Retrieving Data from a <code>CachedRowSet</code> Object</h3>* Data is retrieved from a <code>CachedRowSet</code> object by using the* getter methods inherited from the <code>ResultSet</code>* interface. The following examples, in which <code>crs</code> is a* <code>CachedRowSet</code>* object, demonstrate how to iterate through the rows, retrieving the column* values in each row. The first example uses the version of the* getter methods that take a column number; the second example* uses the version that takes a column name. Column numbers are generally* used when the <code>RowSet</code> object's command* is of the form <code>SELECT * FROM TABLENAME</code>; column names are most* commonly used when the command specifies columns by name.* <PRE>* while (crs.next()) {* String name = crs.getString(1);* int id = crs.getInt(2);* Clob comment = crs.getClob(3);* short dept = crs.getShort(4);* System.out.println(name + " " + id + " " + comment + " " + dept);* }* </PRE>** <PRE>* while (crs.next()) {* String name = crs.getString("NAME");* int id = crs.getInt("ID");* Clob comment = crs.getClob("COM");* short dept = crs.getShort("DEPT");* System.out.println(name + " " + id + " " + comment + " " + dept);* }* </PRE>* <h4>2.1 Retrieving <code>RowSetMetaData</code></h4>* An application can get information about the columns in a <code>CachedRowSet</code>* object by calling <code>ResultSetMetaData</code> and <code>RowSetMetaData</code>* methods on a <code>RowSetMetaData</code> object. The following code fragment,* in which <i>crs</i> is a <code>CachedRowSet</code> object, illustrates the process.* The first line creates a <code>RowSetMetaData</code> object with information* about the columns in <i>crs</i>. The method <code>getMetaData</code>,* inherited from the <code>ResultSet</code> interface, returns a* <code>ResultSetMetaData</code> object, which is cast to a* <code>RowSetMetaData</code> object before being assigned to the variable* <i>rsmd</i>. The second line finds out how many columns <i>jrs</i> has, and* the third line gets the JDBC type of values stored in the second column of* <code>jrs</code>.* <PRE>* RowSetMetaData rsmd = (RowSetMetaData)crs.getMetaData();* int count = rsmd.getColumnCount();* int type = rsmd.getColumnType(2);* </PRE>* The <code>RowSetMetaData</code> interface differs from the* <code>ResultSetMetaData</code> interface in two ways.* <UL>* <LI><i>It includes <code>setter</code> methods:</i> A <code>RowSet</code>* object uses these methods internally when it is populated with data from a* different <code>ResultSet</code> object.** <LI><i>It contains fewer <code>getter</code> methods:</i> Some* <code>ResultSetMetaData</code> methods to not apply to a <code>RowSet</code>* object. For example, methods retrieving whether a column value is writable* or read only do not apply because all of a <code>RowSet</code> object's* columns will be writable or read only, depending on whether the rowset is* updatable or not.* </UL>* NOTE: In order to return a <code>RowSetMetaData</code> object, implementations must* override the <code>getMetaData()</code> method defined in* <code>java.sql.ResultSet</code> and return a <code>RowSetMetaData</code> object.** <h3>3.0 Updating a <code>CachedRowSet</code> Object</h3>* Updating a <code>CachedRowSet</code> object is similar to updating a* <code>ResultSet</code> object, but because the rowset is not connected to* its data source while it is being updated, it must take an additional step* to effect changes in its underlying data source. After calling the method* <code>updateRow</code> or <code>insertRow</code>, a* <code>CachedRowSet</code>* object must also call the method <code>acceptChanges</code> to have updates* written to the data source. The following example, in which the cursor is* on a row in the <code>CachedRowSet</code> object <i>crs</i>, shows* the code required to update two column values in the current row and also* update the <code>RowSet</code> object's underlying data source.* <PRE>* crs.updateShort(3, 58);* crs.updateInt(4, 150000);* crs.updateRow();* crs.acceptChanges();* </PRE>* <P>* The next example demonstrates moving to the insert row, building a new* row on the insert row, inserting it into the rowset, and then calling the* method <code>acceptChanges</code> to add the new row to the underlying data* source. Note that as with the getter methods, the updater methods may take* either a column index or a column name to designate the column being acted upon.* <PRE>* crs.moveToInsertRow();* crs.updateString("Name", "Shakespeare");* crs.updateInt("ID", 10098347);* crs.updateShort("Age", 58);* crs.updateInt("Sal", 150000);* crs.insertRow();* crs.moveToCurrentRow();* crs.acceptChanges();* </PRE>* <P>* NOTE: Where the <code>insertRow()</code> method inserts the contents of a* <code>CachedRowSet</code> object's insert row is implementation-defined.* The reference implementation for the <code>CachedRowSet</code> interface* inserts a new row immediately following the current row, but it could be* implemented to insert new rows in any number of other places.* <P>* Another thing to note about these examples is how they use the method* <code>acceptChanges</code>. It is this method that propagates changes in* a <code>CachedRowSet</code> object back to the underlying data source,* calling on the <code>RowSet</code> object's writer internally to write* changes to the data source. To do this, the writer has to incur the expense* of establishing a connection with that data source. The* preceding two code fragments call the method <code>acceptChanges</code>* immediately after calling <code>updateRow</code> or <code>insertRow</code>.* However, when there are multiple rows being changed, it is more efficient to call* <code>acceptChanges</code> after all calls to <code>updateRow</code>* and <code>insertRow</code> have been made. If <code>acceptChanges</code>* is called only once, only one connection needs to be established.** <h3>4.0 Updating the Underlying Data Source</h3>* When the method <code>acceptChanges</code> is executed, the* <code>CachedRowSet</code> object's writer, a <code>RowSetWriterImpl</code>* object, is called behind the scenes to write the changes made to the* rowset to the underlying data source. The writer is implemented to make a* connection to the data source and write updates to it.* <P>* A writer is made available through an implementation of the* <code>SyncProvider</code> interface, as discussed in section 1,* "Creating a <code>CachedRowSet</code> Object."* The default reference implementation provider, <code>RIOptimisticProvider</code>,* has its writer implemented to use an optimistic concurrency control* mechanism. That is, it maintains no locks in the underlying database while* the rowset is disconnected from the database and simply checks to see if there* are any conflicts before writing data to the data source. If there are any* conflicts, it does not write anything to the data source.* <P>* The reader/writer facility* provided by the <code>SyncProvider</code> class is pluggable, allowing for the* customization of data retrieval and updating. If a different concurrency* control mechanism is desired, a different implementation of* <code>SyncProvider</code> can be plugged in using the method* <code>setSyncProvider</code>.* <P>* In order to use the optimistic concurrency control routine, the* <code>RIOptismisticProvider</code> maintains both its current* value and its original value (the value it had immediately preceding the* current value). Note that if no changes have been made to the data in a* <code>RowSet</code> object, its current values and its original values are the same,* both being the values with which the <code>RowSet</code> object was initially* populated. However, once any values in the <code>RowSet</code> object have been* changed, the current values and the original values will be different, though at* this stage, the original values are still the initial values. With any subsequent* changes to data in a <code>RowSet</code> object, its original values and current* values will still differ, but its original values will be the values that* were previously the current values.* <P>* Keeping track of original values allows the writer to compare the <code>RowSet</code>* object's original value with the value in the database. If the values in* the database differ from the <code>RowSet</code> object's original values, which means that* the values in the database have been changed, there is a conflict.* Whether a writer checks for conflicts, what degree of checking it does, and how* it handles conflicts all depend on how it is implemented.** <h3>5.0 Registering and Notifying Listeners</h3>* Being JavaBeans components, all rowsets participate in the JavaBeans event* model, inheriting methods for registering listeners and notifying them of* changes from the <code>BaseRowSet</code> class. A listener for a* <code>CachedRowSet</code> object is a component that wants to be notified* whenever there is a change in the rowset. For example, if a* <code>CachedRowSet</code> object contains the results of a query and* those* results are being displayed in, say, a table and a bar graph, the table and* bar graph could be registered as listeners with the rowset so that they can* update themselves to reflect changes. To become listeners, the table and* bar graph classes must implement the <code>RowSetListener</code> interface.* Then they can be added to the <Code>CachedRowSet</code> object's list of* listeners, as is illustrated in the following lines of code.* <PRE>* crs.addRowSetListener(table);* crs.addRowSetListener(barGraph);* </PRE>* Each <code>CachedRowSet</code> method that moves the cursor or changes* data also notifies registered listeners of the changes, so* <code>table</code> and <code>barGraph</code> will be notified when there is* a change in <code>crs</code>.** <h3>6.0 Passing Data to Thin Clients</h3>* One of the main reasons to use a <code>CachedRowSet</code> object is to* pass data between different components of an application. Because it is* serializable, a <code>CachedRowSet</code> object can be used, for example,* to send the result of a query executed by an enterprise JavaBeans component* running in a server environment over a network to a client running in a* web browser.* <P>* While a <code>CachedRowSet</code> object is disconnected, it can be much* leaner than a <code>ResultSet</code> object with the same data.* As a result, it can be especially suitable for sending data to a thin client* such as a PDA, where it would be inappropriate to use a JDBC driver* due to resource limitations or security considerations.* Thus, a <code>CachedRowSet</code> object provides a means to "get rows in"* without the need to implement the full JDBC API.** <h3>7.0 Scrolling and Updating</h3>* A second major use for <code>CachedRowSet</code> objects is to provide* scrolling and updating for <code>ResultSet</code> objects that* do not provide these capabilities themselves. In other words, a* <code>CachedRowSet</code> object can be used to augment the* capabilities of a JDBC technology-enabled driver (hereafter called a* "JDBC driver") when the DBMS does not provide full support for scrolling and* updating. To achieve the effect of making a non-scrollble and read-only* <code>ResultSet</code> object scrollable and updatable, a programmer* simply needs to create a <code>CachedRowSet</code> object populated* with that <code>ResultSet</code> object's data. This is demonstrated* in the following code fragment, where <code>stmt</code> is a* <code>Statement</code> object.* <PRE>* ResultSet rs = stmt.executeQuery("SELECT * FROM EMPLOYEES");* CachedRowSetImpl crs = new CachedRowSetImpl();* crs.populate(rs);* </PRE>* <P>* The object <code>crs</code> now contains the data from the table* <code>EMPLOYEES</code>, just as the object <code>rs</code> does.* The difference is that the cursor for <code>crs</code> can be moved* forward, backward, or to a particular row even if the cursor for* <code>rs</code> can move only forward. In addition, <code>crs</code> is* updatable even if <code>rs</code> is not because by default, a* <code>CachedRowSet</code> object is both scrollable and updatable.* <P>* In summary, a <code>CachedRowSet</code> object can be thought of as simply* a disconnected set of rows that are being cached outside of a data source.* Being thin and serializable, it can easily be sent across a wire,* and it is well suited to sending data to a thin client. However, a* <code>CachedRowSet</code> object does have a limitation: It is limited in* size by the amount of data it can store in memory at one time.** <h3>8.0 Getting Universal Data Access</h3>* Another advantage of the <code>CachedRowSet</code> class is that it makes it* possible to retrieve and store data from sources other than a relational* database. The reader for a rowset can be implemented to read and populate* its rowset with data from any tabular data source, including a spreadsheet* or flat file.* Because both a <code>CachedRowSet</code> object and its metadata can be* created from scratch, a component that acts as a factory for rowsets* can use this capability to create a rowset containing data from* non-SQL data sources. Nevertheless, it is expected that most of the time,* <code>CachedRowSet</code> objects will contain data that was fetched* from an SQL database using the JDBC API.** <h3>9.0 Setting Properties</h3>* All rowsets maintain a set of properties, which will usually be set using* a tool. The number and kinds of properties a rowset has will vary,* depending on what the rowset does and how it gets its data. For example,* rowsets that get their data from a <code>ResultSet</code> object need to* set the properties that are required for making a database connection.* If a rowset uses the <code>DriverManager</code> facility to make a* connection, it needs to set a property for the JDBC URL that identifies* the appropriate driver, and it needs to set the properties that give the* user name and password.* If, on the other hand, the rowset uses a <code>DataSource</code> object* to make the connection, which is the preferred method, it does not need to* set the property for the JDBC URL. Instead, it needs to set* properties for the logical name of the data source, for the user name,* and for the password.* <P>* NOTE: In order to use a <code>DataSource</code> object for making a* connection, the <code>DataSource</code> object must have been registered* with a naming service that uses the Java Naming and Directory* Interface™ (JNDI) API. This registration* is usually done by a person acting in the capacity of a system* administrator.* <P>* In order to be able to populate itself with data from a database, a rowset* needs to set a command property. This property is a query that is a* <code>PreparedStatement</code> object, which allows the query to have* parameter placeholders that are set at run time, as opposed to design time.* To set these placeholder parameters with values, a rowset provides* setter methods for setting values of each data type,* similar to the setter methods provided by the <code>PreparedStatement</code>* interface.* <P>* The following code fragment illustrates how the <code>CachedRowSet</code>* object <code>crs</code> might have its command property set. Note that if a* tool is used to set properties, this is the code that the tool would use.* <PRE>{@code* crs.setCommand("SELECT FIRST_NAME, LAST_NAME, ADDRESS FROM CUSTOMERS " +* "WHERE CREDIT_LIMIT > ? AND REGION = ?");* } </PRE>* <P>* The values that will be used to set the command's placeholder parameters are* contained in the <code>RowSet</code> object's <code>params</code> field, which is a* <code>Vector</code> object.* The <code>CachedRowSet</code> class provides a set of setter* methods for setting the elements in its <code>params</code> field. The* following code fragment demonstrates setting the two parameters in the* query from the previous example.* <PRE>* crs.setInt(1, 5000);* crs.setString(2, "West");* </PRE>* <P>* The <code>params</code> field now contains two elements, each of which is* an array two elements long. The first element is the parameter number;* the second is the value to be set.* In this case, the first element of <code>params</code> is* <code>1</code>, <code>5000</code>, and the second element is <code>2</code>,* <code>"West"</code>. When an application calls the method* <code>execute</code>, it will in turn call on this <code>RowSet</code> object's reader,* which will in turn invoke its <code>readData</code> method. As part of* its implementation, <code>readData</code> will get the values in* <code>params</code> and use them to set the command's placeholder* parameters.* The following code fragment gives an idea of how the reader* does this, after obtaining the <code>Connection</code> object* <code>con</code>.* <PRE>{@code* PreparedStatement pstmt = con.prepareStatement(crs.getCommand());* reader.decodeParams();* // decodeParams figures out which setter methods to use and does something* // like the following:* // for (i = 0; i < params.length; i++) {* // pstmt.setObject(i + 1, params[i]);* // }* }</PRE>* <P>* At this point, the command for <code>crs</code> is the query {@code "SELECT* FIRST_NAME, LAST_NAME, ADDRESS FROM CUSTOMERS WHERE CREDIT_LIMIT > 5000* AND REGION = "West"}. After the <code>readData</code> method executes* this command with the following line of code, it will have the data from* <code>rs</code> with which to populate <code>crs</code>.* <PRE>{@code* ResultSet rs = pstmt.executeQuery();* }</PRE>* <P>* The preceding code fragments give an idea of what goes on behind the* scenes; they would not appear in an application, which would not invoke* methods like <code>readData</code> and <code>decodeParams</code>.* In contrast, the following code fragment shows what an application might do.* It sets the rowset's command, sets the command's parameters, and executes* the command. Simply by calling the <code>execute</code> method,* <code>crs</code> populates itself with the requested data from the* table <code>CUSTOMERS</code>.* <PRE>{@code* crs.setCommand("SELECT FIRST_NAME, LAST_NAME, ADDRESS FROM CUSTOMERS" +* "WHERE CREDIT_LIMIT > ? AND REGION = ?");* crs.setInt(1, 5000);* crs.setString(2, "West");* crs.execute();* }</PRE>** <h3>10.0 Paging Data</h3>* Because a <code>CachedRowSet</code> object stores data in memory,* the amount of data that it can contain at any one* time is determined by the amount of memory available. To get around this limitation,* a <code>CachedRowSet</code> object can retrieve data from a <code>ResultSet</code>* object in chunks of data, called <i>pages</i>. To take advantage of this mechanism,* an application sets the number of rows to be included in a page using the method* <code>setPageSize</code>. In other words, if the page size is set to five, a chunk* of five rows of* data will be fetched from the data source at one time. An application can also* optionally set the maximum number of rows that may be fetched at one time. If the* maximum number of rows is set to zero, or no maximum number of rows is set, there is* no limit to the number of rows that may be fetched at a time.* <P>* After properties have been set,* the <code>CachedRowSet</code> object must be populated with data* using either the method <code>populate</code> or the method <code>execute</code>.* The following lines of code demonstrate using the method <code>populate</code>.* Note that this version of the method takes two parameters, a <code>ResultSet</code>* handle and the row in the <code>ResultSet</code> object from which to start* retrieving rows.* <PRE>* CachedRowSet crs = new CachedRowSetImpl();* crs.setMaxRows(20);* crs.setPageSize(4);* crs.populate(rsHandle, 10);* </PRE>* When this code runs, <i>crs</i> will be populated with four rows from* <i>rsHandle</i> starting with the tenth row.* <P>* The next code fragment shows populating a <code>CachedRowSet</code> object using the* method <code>execute</code>, which may or may not take a <code>Connection</code>* object as a parameter. This code passes <code>execute</code> the <code>Connection</code>* object <i>conHandle</i>.* <P>* Note that there are two differences between the following code* fragment and the previous one. First, the method <code>setMaxRows</code> is not* called, so there is no limit set for the number of rows that <i>crs</i> may contain.* (Remember that <i>crs</i> always has the overriding limit of how much data it can* store in memory.) The second difference is that the you cannot pass the method* <code>execute</code> the number of the row in the <code>ResultSet</code> object* from which to start retrieving rows. This method always starts with the first row.* <PRE>* CachedRowSet crs = new CachedRowSetImpl();* crs.setPageSize(5);* crs.execute(conHandle);* </PRE>* After this code has run, <i>crs</i> will contain five rows of data from the* <code>ResultSet</code> object produced by the command for <i>crs</i>. The writer* for <i>crs</i> will use <i>conHandle</i> to connect to the data source and* execute the command for <i>crs</i>. An application is then able to operate on the* data in <i>crs</i> in the same way that it would operate on data in any other* <code>CachedRowSet</code> object.* <P>* To access the next page (chunk of data), an application calls the method* <code>nextPage</code>. This method creates a new <code>CachedRowSet</code> object* and fills it with the next page of data. For example, assume that the* <code>CachedRowSet</code> object's command returns a <code>ResultSet</code> object* <i>rs</i> with 1000 rows of data. If the page size has been set to 100, the first* call to the method <code>nextPage</code> will create a <code>CachedRowSet</code> object* containing the first 100 rows of <i>rs</i>. After doing what it needs to do with the* data in these first 100 rows, the application can again call the method* <code>nextPage</code> to create another <code>CachedRowSet</code> object* with the second 100 rows from <i>rs</i>. The data from the first <code>CachedRowSet</code>* object will no longer be in memory because it is replaced with the data from the* second <code>CachedRowSet</code> object. After the tenth call to the method <code>nextPage</code>,* the tenth <code>CachedRowSet</code> object will contain the last 100 rows of data from* <i>rs</i>, which are stored in memory. At any given time, the data from only one* <code>CachedRowSet</code> object is stored in memory.* <P>* The method <code>nextPage</code> returns <code>true</code> as long as the current* page is not the last page of rows and <code>false</code> when there are no more pages.* It can therefore be used in a <code>while</code> loop to retrieve all of the pages,* as is demonstrated in the following lines of code.* <PRE>* CachedRowSet crs = CachedRowSetImpl();* crs.setPageSize(100);* crs.execute(conHandle);** while(crs.nextPage()) {* while(crs.next()) {* . . . // operate on chunks (of 100 rows each) in crs,* // row by row* }* }* </PRE>* After this code fragment has been run, the application will have traversed all* 1000 rows, but it will have had no more than 100 rows in memory at a time.* <P>* The <code>CachedRowSet</code> interface also defines the method <code>previousPage</code>.* Just as the method <code>nextPage</code> is analogous to the <code>ResultSet</code>* method <code>next</code>, the method <code>previousPage</code> is analogous to* the <code>ResultSet</code> method <code>previous</code>. Similar to the method* <code>nextPage</code>, <code>previousPage</code> creates a <code>CachedRowSet</code>* object containing the number of rows set as the page size. So, for instance, the* method <code>previousPage</code> could be used in a <code>while</code> loop at* the end of the preceding code fragment to navigate back through the pages from the last* page to the first page.* The method <code>previousPage</code> is also similar to <code>nextPage</code>* in that it can be used in a <code>while</code>* loop, except that it returns <code>true</code> as long as there is another page* preceding it and <code>false</code> when there are no more pages ahead of it.* <P>* By positioning the cursor after the last row for each page,* as is done in the following code fragment, the method <code>previous</code>* navigates from the last row to the first row in each page.* The code could also have left the cursor before the first row on each page and then* used the method <code>next</code> in a <code>while</code> loop to navigate each page* from the first row to the last row.* <P>* The following code fragment assumes a continuation from the previous code fragment,* meaning that the cursor for the tenth <code>CachedRowSet</code> object is on the* last row. The code moves the cursor to after the last row so that the first* call to the method <code>previous</code> will put the cursor back on the last row.* After going through all of the rows in the last page (the <code>CachedRowSet</code>* object <i>crs</i>), the code then enters* the <code>while</code> loop to get to the ninth page, go through the rows backwards,* go to the eighth page, go through the rows backwards, and so on to the first row* of the first page.** <PRE>* crs.afterLast();* while(crs.previous()) {* . . . // navigate through the rows, last to first* {* while(crs.previousPage()) {* crs.afterLast();* while(crs.previous()) {* . . . // go from the last row to the first row of each page* }* }* </PRE>** @author Jonathan Bruce*/public interface CachedRowSet extends RowSet, Joinable {/*** Populates this <code>CachedRowSet</code> object with data from* the given <code>ResultSet</code> object.* <P>* This method can be used as an alternative to the <code>execute</code> method when an* application has a connection to an open <code>ResultSet</code> object.* Using the method <code>populate</code> can be more efficient than using* the version of the <code>execute</code> method that takes no parameters* because it does not open a new connection and re-execute this* <code>CachedRowSet</code> object's command. Using the <code>populate</code>* method is more a matter of convenience when compared to using the version* of <code>execute</code> that takes a <code>ResultSet</code> object.** @param data the <code>ResultSet</code> object containing the data* to be read into this <code>CachedRowSet</code> object* @throws SQLException if a null <code>ResultSet</code> object is supplied* or this <code>CachedRowSet</code> object cannot* retrieve the associated <code>ResultSetMetaData</code> object* @see #execute* @see java.sql.ResultSet* @see java.sql.ResultSetMetaData*/public void populate(ResultSet data) throws SQLException;/*** Populates this <code>CachedRowSet</code> object with data, using the* given connection to produce the result set from which the data will be read.* This method should close any database connections that it creates to* ensure that this <code>CachedRowSet</code> object is disconnected except when* it is reading data from its data source or writing data to its data source.* <P>* The reader for this <code>CachedRowSet</code> object* will use <i>conn</i> to establish a connection to the data source* so that it can execute the rowset's command and read data from the* the resulting <code>ResultSet</code> object into this* <code>CachedRowSet</code> object. This method also closes <i>conn</i>* after it has populated this <code>CachedRowSet</code> object.* <P>* If this method is called when an implementation has already been* populated, the contents and the metadata are (re)set. Also, if this method is* called before the method <code>acceptChanges</code> has been called* to commit outstanding updates, those updates are lost.** @param conn a standard JDBC <code>Connection</code> object with valid* properties* @throws SQLException if an invalid <code>Connection</code> object is supplied* or an error occurs in establishing the connection to the* data source* @see #populate* @see java.sql.Connection*/public void execute(Connection conn) throws SQLException;/*** Propagates row update, insert and delete changes made to this* <code>CachedRowSet</code> object to the underlying data source.* <P>* This method calls on this <code>CachedRowSet</code> object's writer* to do the work behind the scenes.* Standard <code>CachedRowSet</code> implementations should use the* <code>SyncFactory</code> singleton* to obtain a <code>SyncProvider</code> instance providing a* <code>RowSetWriter</code> object (writer). The writer will attempt* to propagate changes made in this <code>CachedRowSet</code> object* back to the data source.* <P>* When the method <code>acceptChanges</code> executes successfully, in* addition to writing changes to the data source, it* makes the values in the current row be the values in the original row.* <P>* Depending on the synchronization level of the <code>SyncProvider</code>* implementation being used, the writer will compare the original values* with those in the data source to check for conflicts. When there is a conflict,* the <code>RIOptimisticProvider</code> implementation, for example, throws a* <code>SyncProviderException</code> and does not write anything to the* data source.* <P>* An application may choose to catch the <code>SyncProviderException</code>* object and retrieve the <code>SyncResolver</code> object it contains.* The <code>SyncResolver</code> object lists the conflicts row by row and* sets a lock on the data source to avoid further conflicts while the* current conflicts are being resolved.* Further, for each conflict, it provides methods for examining the conflict* and setting the value that should be persisted in the data source.* After all conflicts have been resolved, an application must call the* <code>acceptChanges</code> method again to write resolved values to the* data source. If all of the values in the data source are already the* values to be persisted, the method <code>acceptChanges</code> does nothing.* <P>* Some provider implementations may use locks to ensure that there are no* conflicts. In such cases, it is guaranteed that the writer will succeed in* writing changes to the data source when the method <code>acceptChanges</code>* is called. This method may be called immediately after the methods* <code>updateRow</code>, <code>insertRow</code>, or <code>deleteRow</code>* have been called, but it is more efficient to call it only once after* all changes have been made so that only one connection needs to be* established.* <P>* Note: The <code>acceptChanges()</code> method will determine if the* <code>COMMIT_ON_ACCEPT_CHANGES</code> is set to true or not. If it is set* to true, all updates in the synchronization are committed to the data* source. Otherwise, the application <b>must</b> explicity call the* <code>commit()</code> or <code>rollback()</code> methods as appropriate.** @throws SyncProviderException if the underlying* synchronization provider's writer fails to write the updates* back to the data source* @see #acceptChanges(java.sql.Connection)* @see javax.sql.RowSetWriter* @see javax.sql.rowset.spi.SyncFactory* @see javax.sql.rowset.spi.SyncProvider* @see javax.sql.rowset.spi.SyncProviderException* @see javax.sql.rowset.spi.SyncResolver*/public void acceptChanges() throws SyncProviderException;/*** Propagates all row update, insert and delete changes to the* data source backing this <code>CachedRowSet</code> object* using the specified <code>Connection</code> object to establish a* connection to the data source.* <P>* The other version of the <code>acceptChanges</code> method is not passed* a connection because it uses* the <code>Connection</code> object already defined within the <code>RowSet</code>* object, which is the connection used for populating it initially.* <P>* This form of the method <code>acceptChanges</code> is similar to the* form that takes no arguments; however, unlike the other form, this form* can be used only when the underlying data source is a JDBC data source.* The updated <code>Connection</code> properties must be used by the* <code>SyncProvider</code> to reset the <code>RowSetWriter</code>* configuration to ensure that the contents of the <code>CachedRowSet</code>* object are synchronized correctly.* <P>* When the method <code>acceptChanges</code> executes successfully, in* addition to writing changes to the data source, it* makes the values in the current row be the values in the original row.* <P>* Depending on the synchronization level of the <code>SyncProvider</code>* implementation being used, the writer will compare the original values* with those in the data source to check for conflicts. When there is a conflict,* the <code>RIOptimisticProvider</code> implementation, for example, throws a* <code>SyncProviderException</code> and does not write anything to the* data source.* <P>* An application may choose to catch the <code>SyncProviderException</code>* object and retrieve the <code>SyncResolver</code> object it contains.* The <code>SyncResolver</code> object lists the conflicts row by row and* sets a lock on the data source to avoid further conflicts while the* current conflicts are being resolved.* Further, for each conflict, it provides methods for examining the conflict* and setting the value that should be persisted in the data source.* After all conflicts have been resolved, an application must call the* <code>acceptChanges</code> method again to write resolved values to the* data source. If all of the values in the data source are already the* values to be persisted, the method <code>acceptChanges</code> does nothing.* <P>* Some provider implementations may use locks to ensure that there are no* conflicts. In such cases, it is guaranteed that the writer will succeed in* writing changes to the data source when the method <code>acceptChanges</code>* is called. This method may be called immediately after the methods* <code>updateRow</code>, <code>insertRow</code>, or <code>deleteRow</code>* have been called, but it is more efficient to call it only once after* all changes have been made so that only one connection needs to be* established.* <P>* Note: The <code>acceptChanges()</code> method will determine if the* <code>COMMIT_ON_ACCEPT_CHANGES</code> is set to true or not. If it is set* to true, all updates in the synchronization are committed to the data* source. Otherwise, the application <b>must</b> explicity call the* <code>commit</code> or <code>rollback</code> methods as appropriate.** @param con a standard JDBC <code>Connection</code> object* @throws SyncProviderException if the underlying* synchronization provider's writer fails to write the updates* back to the data source* @see #acceptChanges()* @see javax.sql.RowSetWriter* @see javax.sql.rowset.spi.SyncFactory* @see javax.sql.rowset.spi.SyncProvider* @see javax.sql.rowset.spi.SyncProviderException* @see javax.sql.rowset.spi.SyncResolver*/public void acceptChanges(Connection con) throws SyncProviderException;/*** Restores this <code>CachedRowSet</code> object to its original* value, that is, its value before the last set of changes. If there* have been no changes to the rowset or only one set of changes,* the original value is the value with which this <code>CachedRowSet</code> object* was populated; otherwise, the original value is* the value it had immediately before its current value.* <P>* When this method is called, a <code>CachedRowSet</code> implementation* must ensure that all updates, inserts, and deletes to the current* rowset instance are replaced by the previous values. In addition,* the cursor should be* reset to the first row and a <code>rowSetChanged</code> event* should be fired to notify all registered listeners.** @throws SQLException if an error occurs rolling back the current value of* this <code>CachedRowSet</code> object to its previous value* @see javax.sql.RowSetListener#rowSetChanged*/public void restoreOriginal() throws SQLException;/*** Releases the current contents of this <code>CachedRowSet</code>* object and sends a <code>rowSetChanged</code> event to all* registered listeners. Any outstanding updates are discarded and* the rowset contains no rows after this method is called. There* are no interactions with the underlying data source, and any rowset* content, metadata, and content updates should be non-recoverable.* <P>* This <code>CachedRowSet</code> object should lock until its contents and* associated updates are fully cleared, thus preventing 'dirty' reads by* other components that hold a reference to this <code>RowSet</code> object.* In addition, the contents cannot be released* until all all components reading this <code>CachedRowSet</code> object* have completed their reads. This <code>CachedRowSet</code> object* should be returned to normal behavior after firing the* <code>rowSetChanged</code> event.* <P>* The metadata, including JDBC properties and Synchronization SPI* properties, are maintained for future use. It is important that* properties such as the <code>command</code> property be* relevant to the originating data source from which this <code>CachedRowSet</code>* object was originally established.* <P>* This method empties a rowset, as opposed to the <code>close</code> method,* which marks the entire rowset as recoverable to allow the garbage collector* the rowset's Java VM resources.** @throws SQLException if an error occurs flushing the contents of this* <code>CachedRowSet</code> object* @see javax.sql.RowSetListener#rowSetChanged* @see java.sql.ResultSet#close*/public void release() throws SQLException;/*** Cancels the deletion of the current row and notifies listeners that* a row has changed. After this method is called, the current row is* no longer marked for deletion. This method can be called at any* time during the lifetime of the rowset.* <P>* In addition, multiple cancellations of row deletions can be made* by adjusting the position of the cursor using any of the cursor* position control methods such as:* <ul>* <li><code>CachedRowSet.absolute</code>* <li><code>CachedRowSet.first</code>* <li><code>CachedRowSet.last</code>* </ul>** @throws SQLException if (1) the current row has not been deleted or* (2) the cursor is on the insert row, before the first row, or* after the last row* @see javax.sql.rowset.CachedRowSet#undoInsert* @see java.sql.ResultSet#cancelRowUpdates*/public void undoDelete() throws SQLException;/*** Immediately removes the current row from this <code>CachedRowSet</code>* object if the row has been inserted, and also notifies listeners that a* row has changed. This method can be called at any time during the* lifetime of a rowset and assuming the current row is within* the exception limitations (see below), it cancels the row insertion* of the current row.* <P>* In addition, multiple cancellations of row insertions can be made* by adjusting the position of the cursor using any of the cursor* position control methods such as:* <ul>* <li><code>CachedRowSet.absolute</code>* <li><code>CachedRowSet.first</code>* <li><code>CachedRowSet.last</code>* </ul>** @throws SQLException if (1) the current row has not been inserted or (2)* the cursor is before the first row, after the last row, or on the* insert row* @see javax.sql.rowset.CachedRowSet#undoDelete* @see java.sql.ResultSet#cancelRowUpdates*/public void undoInsert() throws SQLException;/*** Immediately reverses the last update operation if the* row has been modified. This method can be* called to reverse updates on all columns until all updates in a row have* been rolled back to their state just prior to the last synchronization* (<code>acceptChanges</code>) or population. This method may also be called* while performing updates to the insert row.* <P>* <code>undoUpdate</code> may be called at any time during the lifetime of a* rowset; however, after a synchronization has occurred, this method has no* effect until further modification to the rowset data has occurred.** @throws SQLException if the cursor is before the first row or after the last* row in in this <code>CachedRowSet</code> object* @see #undoDelete* @see #undoInsert* @see java.sql.ResultSet#cancelRowUpdates*/public void undoUpdate() throws SQLException;/*** Indicates whether the designated column in the current row of this* <code>CachedRowSet</code> object has been updated.** @param idx an <code>int</code> identifying the column to be checked for updates* @return <code>true</code> if the designated column has been visibly updated;* <code>false</code> otherwise* @throws SQLException if the cursor is on the insert row, before the first row,* or after the last row* @see java.sql.DatabaseMetaData#updatesAreDetected*/public boolean columnUpdated(int idx) throws SQLException;/*** Indicates whether the designated column in the current row of this* <code>CachedRowSet</code> object has been updated.** @param columnName a <code>String</code> object giving the name of the* column to be checked for updates* @return <code>true</code> if the column has been visibly updated;* <code>false</code> otherwise* @throws SQLException if the cursor is on the insert row, before the first row,* or after the last row* @see java.sql.DatabaseMetaData#updatesAreDetected*/public boolean columnUpdated(String columnName) throws SQLException;/*** Converts this <code>CachedRowSet</code> object to a <code>Collection</code>* object that contains all of this <code>CachedRowSet</code> object's data.* Implementations have some latitude in* how they can represent this <code>Collection</code> object because of the* abstract nature of the <code>Collection</code> framework.* Each row must be fully represented in either a* general purpose <code>Collection</code> implementation or a specialized* <code>Collection</code> implementation, such as a <code>TreeMap</code>* object or a <code>Vector</code> object.* An SQL <code>NULL</code> column value must be represented as a <code>null</code>* in the Java programming language.* <P>* The standard reference implementation for the <code>CachedRowSet</code>* interface uses a <code>TreeMap</code> object for the rowset, with the* values in each row being contained in <code>Vector</code> objects. It is* expected that most implementations will do the same.* <P>* The <code>TreeMap</code> type of collection guarantees that the map will be in* ascending key order, sorted according to the natural order for the* key's class.* Each key references a <code>Vector</code> object that corresponds to one* row of a <code>RowSet</code> object. Therefore, the size of each* <code>Vector</code> object must be exactly equal to the number of* columns in the <code>RowSet</code> object.* The key used by the <code>TreeMap</code> collection is determined by the* implementation, which may choose to leverage a set key that is* available within the internal <code>RowSet</code> tabular structure by* virtue of a key already set either on the <code>RowSet</code> object* itself or on the underlying SQL data.* <P>** @return a <code>Collection</code> object that contains the values in* each row in this <code>CachedRowSet</code> object* @throws SQLException if an error occurs generating the collection* @see #toCollection(int)* @see #toCollection(String)*/public Collection<?> toCollection() throws SQLException;/*** Converts the designated column in this <code>CachedRowSet</code> object* to a <code>Collection</code> object. Implementations have some latitude in* how they can represent this <code>Collection</code> object because of the* abstract nature of the <code>Collection</code> framework.* Each column value should be fully represented in either a* general purpose <code>Collection</code> implementation or a specialized* <code>Collection</code> implementation, such as a <code>Vector</code> object.* An SQL <code>NULL</code> column value must be represented as a <code>null</code>* in the Java programming language.* <P>* The standard reference implementation uses a <code>Vector</code> object* to contain the column values, and it is expected* that most implementations will do the same. If a <code>Vector</code> object* is used, it size must be exactly equal to the number of rows* in this <code>CachedRowSet</code> object.** @param column an <code>int</code> indicating the column whose values* are to be represented in a <code>Collection</code> object* @return a <code>Collection</code> object that contains the values* stored in the specified column of this <code>CachedRowSet</code>* object* @throws SQLException if an error occurs generating the collection or* an invalid column id is provided* @see #toCollection* @see #toCollection(String)*/public Collection<?> toCollection(int column) throws SQLException;/*** Converts the designated column in this <code>CachedRowSet</code> object* to a <code>Collection</code> object. Implementations have some latitude in* how they can represent this <code>Collection</code> object because of the* abstract nature of the <code>Collection</code> framework.* Each column value should be fully represented in either a* general purpose <code>Collection</code> implementation or a specialized* <code>Collection</code> implementation, such as a <code>Vector</code> object.* An SQL <code>NULL</code> column value must be represented as a <code>null</code>* in the Java programming language.* <P>* The standard reference implementation uses a <code>Vector</code> object* to contain the column values, and it is expected* that most implementations will do the same. If a <code>Vector</code> object* is used, it size must be exactly equal to the number of rows* in this <code>CachedRowSet</code> object.** @param column a <code>String</code> object giving the name of the* column whose values are to be represented in a collection* @return a <code>Collection</code> object that contains the values* stored in the specified column of this <code>CachedRowSet</code>* object* @throws SQLException if an error occurs generating the collection or* an invalid column id is provided* @see #toCollection* @see #toCollection(int)*/public Collection<?> toCollection(String column) throws SQLException;/*** Retrieves the <code>SyncProvider</code> implementation for this* <code>CachedRowSet</code> object. Internally, this method is used by a rowset* to trigger read or write actions between the rowset* and the data source. For example, a rowset may need to get a handle* on the the rowset reader (<code>RowSetReader</code> object) from the* <code>SyncProvider</code> to allow the rowset to be populated.* <pre>* RowSetReader rowsetReader = null;* SyncProvider provider =* SyncFactory.getInstance("javax.sql.rowset.provider.RIOptimisticProvider");* if (provider instanceof RIOptimisticProvider) {* rowsetReader = provider.getRowSetReader();* }* </pre>* Assuming <i>rowsetReader</i> is a private, accessible field within* the rowset implementation, when an application calls the <code>execute</code>* method, it in turn calls on the reader's <code>readData</code> method* to populate the <code>RowSet</code> object.*<pre>* rowsetReader.readData((RowSetInternal)this);* </pre>* <P>* In addition, an application can use the <code>SyncProvider</code> object* returned by this method to call methods that return information about the* <code>SyncProvider</code> object, including information about the* vendor, version, provider identification, synchronization grade, and locks* it currently has set.** @return the <code>SyncProvider</code> object that was set when the rowset* was instantiated, or if none was was set, the default provider* @throws SQLException if an error occurs while returning the* <code>SyncProvider</code> object* @see #setSyncProvider*/public SyncProvider getSyncProvider() throws SQLException;/*** Sets the <code>SyncProvider</code> object for this <code>CachedRowSet</code>* object to the one specified. This method* allows the <code>SyncProvider</code> object to be reset.* <P>* A <code>CachedRowSet</code> implementation should always be instantiated* with an available <code>SyncProvider</code> mechanism, but there are* cases where resetting the <code>SyncProvider</code> object is desirable* or necessary. For example, an application might want to use the default* <code>SyncProvider</code> object for a time and then choose to use a provider* that has more recently become available and better fits its needs.* <P>* Resetting the <code>SyncProvider</code> object causes the* <code>RowSet</code> object to request a new <code>SyncProvider</code> implementation* from the <code>SyncFactory</code>. This has the effect of resetting* all previous connections and relationships with the originating* data source and can potentially drastically change the synchronization* behavior of a disconnected rowset.** @param provider a <code>String</code> object giving the fully qualified class* name of a <code>SyncProvider</code> implementation* @throws SQLException if an error occurs while attempting to reset the* <code>SyncProvider</code> implementation* @see #getSyncProvider*/public void setSyncProvider(String provider) throws SQLException;/*** Returns the number of rows in this <code>CachedRowSet</code>* object.** @return number of rows in the rowset*/public int size();/*** Sets the metadata for this <code>CachedRowSet</code> object with* the given <code>RowSetMetaData</code> object. When a* <code>RowSetReader</code> object is reading the contents of a rowset,* it creates a <code>RowSetMetaData</code> object and initializes* it using the methods in the <code>RowSetMetaData</code> implementation.* The reference implementation uses the <code>RowSetMetaDataImpl</code>* class. When the reader has completed reading the rowset contents,* this method is called internally to pass the <code>RowSetMetaData</code>* object to the rowset.** @param md a <code>RowSetMetaData</code> object containing* metadata about the columns in this <code>CachedRowSet</code> object* @throws SQLException if invalid metadata is supplied to the* rowset*/public void setMetaData(RowSetMetaData md) throws SQLException;/*** Returns a <code>ResultSet</code> object containing the original value of this* <code>CachedRowSet</code> object.* <P>* The cursor for the <code>ResultSet</code>* object should be positioned before the first row.* In addition, the returned <code>ResultSet</code> object should have the following* properties:* <UL>* <LI>ResultSet.TYPE_SCROLL_INSENSITIVE* <LI>ResultSet.CONCUR_UPDATABLE* </UL>* <P>* The original value for a <code>RowSet</code> object is the value it had before* the last synchronization with the underlying data source. If there have been* no synchronizations, the original value will be the value with which the* <code>RowSet</code> object was populated. This method is called internally* when an application calls the method <code>acceptChanges</code> and the* <code>SyncProvider</code> object has been implemented to check for conflicts.* If this is the case, the writer compares the original value with the value* currently in the data source to check for conflicts.** @return a <code>ResultSet</code> object that contains the original value for* this <code>CachedRowSet</code> object* @throws SQLException if an error occurs producing the* <code>ResultSet</code> object*/public ResultSet getOriginal() throws SQLException;/*** Returns a <code>ResultSet</code> object containing the original value for the* current row only of this <code>CachedRowSet</code> object.* <P>* The cursor for the <code>ResultSet</code>* object should be positioned before the first row.* In addition, the returned <code>ResultSet</code> object should have the following* properties:* <UL>* <LI>ResultSet.TYPE_SCROLL_INSENSITIVE* <LI>ResultSet.CONCUR_UPDATABLE* </UL>** @return the original result set of the row* @throws SQLException if there is no current row* @see #setOriginalRow*/public ResultSet getOriginalRow() throws SQLException;/*** Sets the current row in this <code>CachedRowSet</code> object as the original* row.* <P>* This method is called internally after the any modified values in the current* row have been synchronized with the data source. The current row must be tagged* as no longer inserted, deleted or updated.* <P>* A call to <code>setOriginalRow</code> is irreversible.** @throws SQLException if there is no current row or an error is* encountered resetting the contents of the original row* @see #getOriginalRow*/public void setOriginalRow() throws SQLException;/*** Returns an identifier for the object (table) that was used to* create this <code>CachedRowSet</code> object. This name may be set on multiple occasions,* and the specification imposes no limits on how many times this* may occur or whether standard implementations should keep track* of previous table names.** @return a <code>String</code> object giving the name of the table that is the* source of data for this <code>CachedRowSet</code> object or <code>null</code>* if no name has been set for the table* @throws SQLException if an error is encountered returning the table name* @see javax.sql.RowSetMetaData#getTableName*/public String getTableName() throws SQLException;/*** Sets the identifier for the table from which this <code>CachedRowSet</code>* object was derived to the given table name. The writer uses this name to* determine which table to use when comparing the values in the data source with the* <code>CachedRowSet</code> object's values during a synchronization attempt.* The table identifier also indicates where modified values from this* <code>CachedRowSet</code> object should be written.* <P>* The implementation of this <code>CachedRowSet</code> object may obtain the* the name internally from the <code>RowSetMetaDataImpl</code> object.** @param tabName a <code>String</code> object identifying the table from which this<code>CachedRowSet</code> object was derived; cannot be <code>null</code>* but may be an empty string* @throws SQLException if an error is encountered naming the table or* <i>tabName</i> is <code>null</code>* @see javax.sql.RowSetMetaData#setTableName* @see javax.sql.RowSetWriter* @see javax.sql.rowset.spi.SyncProvider*/public void setTableName(String tabName) throws SQLException;/*** Returns an array containing one or more column numbers indicating the columns* that form a key that uniquely* identifies a row in this <code>CachedRowSet</code> object.** @return an array containing the column number or numbers that indicate which columns* constitute a primary key* for a row in this <code>CachedRowSet</code> object. This array should be* empty if no columns are representative of a primary key.* @throws SQLException if this <code>CachedRowSet</code> object is empty* @see #setKeyColumns* @see Joinable#getMatchColumnIndexes* @see Joinable#getMatchColumnNames*/public int[] getKeyColumns() throws SQLException;/*** Sets this <code>CachedRowSet</code> object's <code>keyCols</code>* field with the given array of column numbers, which forms a key* for uniquely identifying a row in this <code>CachedRowSet</code> object.* <p>* If a <code>CachedRowSet</code> object becomes part of a <code>JoinRowSet</code>* object, the keys defined by this method and the resulting constraints are* maintained if the columns designated as key columns also become match* columns.** @param keys an array of <code>int</code> indicating the columns that form* a primary key for this <code>CachedRowSet</code> object; every* element in the array must be greater than <code>0</code> and* less than or equal to the number of columns in this rowset* @throws SQLException if any of the numbers in the given array* are not valid for this rowset* @see #getKeyColumns* @see Joinable#setMatchColumn(String)* @see Joinable#setMatchColumn(int)*/public void setKeyColumns(int[] keys) throws SQLException;/*** Returns a new <code>RowSet</code> object backed by the same data as* that of this <code>CachedRowSet</code> object. In effect, both* <code>CachedRowSet</code> objects have a cursor over the same data.* As a result, any changes made by a duplicate are visible to the original* and to any other duplicates, just as a change made by the original is visible* to all of its duplicates. If a duplicate calls a method that changes the* underlying data, the method it calls notifies all registered listeners* just as it would when it is called by the original <code>CachedRowSet</code>* object.* <P>* In addition, any <code>RowSet</code> object* created by this method will have the same properties as this* <code>CachedRowSet</code> object. For example, if this <code>CachedRowSet</code>* object is read-only, all of its duplicates will also be read-only. If it is* changed to be updatable, the duplicates also become updatable.* <P>* NOTE: If multiple threads access <code>RowSet</code> objects created from* the <code>createShared()</code> method, the following behavior is specified* to preserve shared data integrity: reads and writes of all* shared <code>RowSet</code> objects should be made serially between each* object and the single underlying tabular structure.** @return a new shared <code>RowSet</code> object that has the same properties* as this <code>CachedRowSet</code> object and that has a cursor over* the same data* @throws SQLException if an error occurs or cloning is not* supported in the underlying platform* @see javax.sql.RowSetEvent* @see javax.sql.RowSetListener*/public RowSet createShared() throws SQLException;/*** Creates a <code>RowSet</code> object that is a deep copy of the data in* this <code>CachedRowSet</code> object. In contrast to* the <code>RowSet</code> object generated from a <code>createShared</code>* call, updates made to the copy of the original <code>RowSet</code> object* must not be visible to the original <code>RowSet</code> object. Also, any* event listeners that are registered with the original* <code>RowSet</code> must not have scope over the new* <code>RowSet</code> copies. In addition, any constraint restrictions* established must be maintained.** @return a new <code>RowSet</code> object that is a deep copy* of this <code>CachedRowSet</code> object and is* completely independent of this <code>CachedRowSet</code> object* @throws SQLException if an error occurs in generating the copy of* the of this <code>CachedRowSet</code> object* @see #createShared* @see #createCopySchema* @see #createCopyNoConstraints* @see javax.sql.RowSetEvent* @see javax.sql.RowSetListener*/public CachedRowSet createCopy() throws SQLException;/*** Creates a <code>CachedRowSet</code> object that is an empty copy of this* <code>CachedRowSet</code> object. The copy* must not contain any contents but only represent the table* structure of the original <code>CachedRowSet</code> object. In addition, primary* or foreign key constraints set in the originating <code>CachedRowSet</code> object must* be equally enforced in the new empty <code>CachedRowSet</code> object.* In contrast to* the <code>RowSet</code> object generated from a <code>createShared</code> method* call, updates made to a copy of this <code>CachedRowSet</code> object with the* <code>createCopySchema</code> method must not be visible to it.* <P>* Applications can form a <code>WebRowSet</code> object from the <code>CachedRowSet</code>* object returned by this method in order* to export the <code>RowSet</code> schema definition to XML for future use.* @return An empty copy of this {@code CachedRowSet} object* @throws SQLException if an error occurs in cloning the structure of this* <code>CachedRowSet</code> object* @see #createShared* @see #createCopySchema* @see #createCopyNoConstraints* @see javax.sql.RowSetEvent* @see javax.sql.RowSetListener*/public CachedRowSet createCopySchema() throws SQLException;/*** Creates a <code>CachedRowSet</code> object that is a deep copy of* this <code>CachedRowSet</code> object's data but is independent of it.* In contrast to* the <code>RowSet</code> object generated from a <code>createShared</code>* method call, updates made to a copy of this <code>CachedRowSet</code> object* must not be visible to it. Also, any* event listeners that are registered with this* <code>CachedRowSet</code> object must not have scope over the new* <code>RowSet</code> object. In addition, any constraint restrictions* established for this <code>CachedRowSet</code> object must <b>not</b> be maintained* in the copy.** @return a new <code>CachedRowSet</code> object that is a deep copy* of this <code>CachedRowSet</code> object and is* completely independent of this <code>CachedRowSet</code> object* @throws SQLException if an error occurs in generating the copy of* the of this <code>CachedRowSet</code> object* @see #createCopy* @see #createShared* @see #createCopySchema* @see javax.sql.RowSetEvent* @see javax.sql.RowSetListener*/public CachedRowSet createCopyNoConstraints() throws SQLException;/*** Retrieves the first warning reported by calls on this <code>RowSet</code> object.* Subsequent warnings on this <code>RowSet</code> object will be chained to the* <code>RowSetWarning</code> object that this method returns.** The warning chain is automatically cleared each time a new row is read.* This method may not be called on a RowSet object that has been closed;* doing so will cause a <code>SQLException</code> to be thrown.** @return RowSetWarning the first <code>RowSetWarning</code>* object reported or null if there are none* @throws SQLException if this method is called on a closed RowSet* @see RowSetWarning*/public RowSetWarning getRowSetWarnings() throws SQLException;/*** Retrieves a <code>boolean</code> indicating whether rows marked* for deletion appear in the set of current rows. If <code>true</code> is* returned, deleted rows are visible with the current rows. If* <code>false</code> is returned, rows are not visible with the set of* current rows. The default value is <code>false</code>.* <P>* Standard rowset implementations may choose to restrict this behavior* due to security considerations or to better fit certain deployment* scenarios. This is left as implementation defined and does not* represent standard behavior.* <P>* Note: Allowing deleted rows to remain visible complicates the behavior* of some standard JDBC <code>RowSet</code> Implementations methods.* However, most rowset users can simply ignore this extra detail because* only very specialized applications will likely want to take advantage of* this feature.** @return <code>true</code> if deleted rows are visible;* <code>false</code> otherwise* @throws SQLException if a rowset implementation is unable to* to determine whether rows marked for deletion are visible* @see #setShowDeleted*/public boolean getShowDeleted() throws SQLException;/*** Sets the property <code>showDeleted</code> to the given* <code>boolean</code> value, which determines whether* rows marked for deletion appear in the set of current rows.* If the value is set to <code>true</code>, deleted rows are immediately* visible with the set of current rows. If the value is set to* <code>false</code>, the deleted rows are set as invisible with the* current set of rows.* <P>* Standard rowset implementations may choose to restrict this behavior* due to security considerations or to better fit certain deployment* scenarios. This is left as implementations defined and does not* represent standard behavior.** @param b <code>true</code> if deleted rows should be shown;* <code>false</code> otherwise* @exception SQLException if a rowset implementation is unable to* to reset whether deleted rows should be visible* @see #getShowDeleted*/public void setShowDeleted(boolean b) throws SQLException;/*** Each <code>CachedRowSet</code> object's <code>SyncProvider</code> contains* a <code>Connection</code> object from the <code>ResultSet</code> or JDBC* properties passed to it's constructors. This method wraps the* <code>Connection</code> commit method to allow flexible* auto commit or non auto commit transactional control support.* <p>* Makes all changes that are performed by the <code>acceptChanges()</code>* method since the previous commit/rollback permanent. This method should* be used only when auto-commit mode has been disabled.** @throws SQLException if a database access error occurs or this* Connection object within this <code>CachedRowSet</code> is in auto-commit mode* @see java.sql.Connection#setAutoCommit*/public void commit() throws SQLException;/*** Each <code>CachedRowSet</code> object's <code>SyncProvider</code> contains* a <code>Connection</code> object from the original <code>ResultSet</code>* or JDBC properties passed to it.* <p>* Undoes all changes made in the current transaction. This method* should be used only when auto-commit mode has been disabled.** @throws SQLException if a database access error occurs or this Connection* object within this <code>CachedRowSet</code> is in auto-commit mode.*/public void rollback() throws SQLException;/*** Each <code>CachedRowSet</code> object's <code>SyncProvider</code> contains* a <code>Connection</code> object from the original <code>ResultSet</code>* or JDBC properties passed to it.* <p>* Undoes all changes made in the current transaction back to the last* <code>Savepoint</code> transaction marker. This method should be used only* when auto-commit mode has been disabled.** @param s A <code>Savepoint</code> transaction marker* @throws SQLException if a database access error occurs or this Connection* object within this <code>CachedRowSet</code> is in auto-commit mode.*/public void rollback(Savepoint s) throws SQLException;/*** Causes the <code>CachedRowSet</code> object's <code>SyncProvider</code>* to commit the changes when <code>acceptChanges()</code> is called. If* set to false, the changes will <b>not</b> be committed until one of the* <code>CachedRowSet</code> interface transaction methods is called.** @deprecated Because this field is final (it is part of an interface),* its value cannot be changed.* @see #commit* @see #rollback*/@Deprecatedpublic static final boolean COMMIT_ON_ACCEPT_CHANGES = true;/*** Notifies registered listeners that a RowSet object in the given RowSetEvent* object has populated a number of additional rows. The <code>numRows</code> parameter* ensures that this event will only be fired every <code>numRow</code>.* <p>* The source of the event can be retrieved with the method event.getSource.** @param event a <code>RowSetEvent</code> object that contains the* <code>RowSet</code> object that is the source of the events* @param numRows when populating, the number of rows interval on which the* <code>CachedRowSet</code> populated should fire; the default value* is zero; cannot be less than <code>fetchSize</code> or zero* @throws SQLException {@code numRows < 0 or numRows < getFetchSize() }*/public void rowSetPopulated(RowSetEvent event, int numRows) throws SQLException;/*** Populates this <code>CachedRowSet</code> object with data from* the given <code>ResultSet</code> object. While related to the <code>populate(ResultSet)</code>* method, an additional parameter is provided to allow starting position within* the <code>ResultSet</code> from where to populate the CachedRowSet* instance.* <P>* This method can be used as an alternative to the <code>execute</code> method when an* application has a connection to an open <code>ResultSet</code> object.* Using the method <code>populate</code> can be more efficient than using* the version of the <code>execute</code> method that takes no parameters* because it does not open a new connection and re-execute this* <code>CachedRowSet</code> object's command. Using the <code>populate</code>* method is more a matter of convenience when compared to using the version* of <code>execute</code> that takes a <code>ResultSet</code> object.** @param startRow the position in the <code>ResultSet</code> from where to start* populating the records in this <code>CachedRowSet</code>* @param rs the <code>ResultSet</code> object containing the data* to be read into this <code>CachedRowSet</code> object* @throws SQLException if a null <code>ResultSet</code> object is supplied* or this <code>CachedRowSet</code> object cannot* retrieve the associated <code>ResultSetMetaData</code> object* @see #execute* @see #populate(ResultSet)* @see java.sql.ResultSet* @see java.sql.ResultSetMetaData*/public void populate(ResultSet rs, int startRow) throws SQLException;/*** Sets the <code>CachedRowSet</code> object's page-size. A <code>CachedRowSet</code>* may be configured to populate itself in page-size sized batches of rows. When* either <code>populate()</code> or <code>execute()</code> are called, the* <code>CachedRowSet</code> fetches an additional page according to the* original SQL query used to populate the RowSet.** @param size the page-size of the <code>CachedRowSet</code>* @throws SQLException if an error occurs setting the <code>CachedRowSet</code>* page size or if the page size is less than 0.*/public void setPageSize(int size) throws SQLException;/*** Returns the page-size for the <code>CachedRowSet</code> object** @return an <code>int</code> page size*/public int getPageSize();/*** Increments the current page of the <code>CachedRowSet</code>. This causes* the <code>CachedRowSet</code> implementation to fetch the next page-size* rows and populate the RowSet, if remaining rows remain within scope of the* original SQL query used to populated the RowSet.** @return true if more pages exist; false if this is the last page* @throws SQLException if an error occurs fetching the next page, or if this* method is called prematurely before populate or execute.*/public boolean nextPage() throws SQLException;/*** Decrements the current page of the <code>CachedRowSet</code>. This causes* the <code>CachedRowSet</code> implementation to fetch the previous page-size* rows and populate the RowSet. The amount of rows returned in the previous* page must always remain within scope of the original SQL query used to* populate the RowSet.** @return true if the previous page is successfully retrieved; false if this* is the first page.* @throws SQLException if an error occurs fetching the previous page, or if* this method is called prematurely before populate or execute.*/public boolean previousPage() throws SQLException;}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。