JDBC_ResultSet和Statement_fetchSize_maxRowsjava
先經過ResultSetType來了解一下ResultSet,看這個類表示什麼含義:mysql
resultSetType 的可選值有: ResultSet.TYPE_FORWARD_ONLY 、ResultSet.TYPE_SCROLL_INSENSITIVE 、ResultSet.TYPE_SCROLL_SENSITIVE 。sql
1 :ResultSet.TYPE_FORWARD_ONLY數據庫
默認的cursor 類型,僅僅支持結果集forward ,不支持backforward ,random ,last ,first 等操做。 服務器
2 :ResultSet.TYPE_SCROLL_INSENSITIVEsession
支持結果集backforward ,random ,last ,first 等操做,對其它session對數據庫中數據作出的更改是不敏感的。dom
3 :ResultSet.TYPE_SCROLL_SENSITIVEfetch
支持結果集backforward ,random ,last ,first 等操做,對其它session對數據庫中數據作出的更改是敏感的,即其餘session 修改了數據庫中的數據,會反應到本結果集中。this
ResultSetConcurrency的可選值有2個:spa
ResultSet.CONCUR_READ_ONLY 在ResultSet中的數據記錄是隻讀的,不能夠修改
ResultSet.CONCUR_UPDATABLE 在ResultSet中的數據記錄能夠任意修改,而後更新到數據庫,能夠插入,刪除,修改。
ResultSetHoldability 的可選值有2 個 :
HOLD_CURSORS_OVER_COMMIT: 在事務commit 或rollback 後,ResultSet 仍然可用。
CLOSE_CURSORS_AT_COMMIT: 在事務commit 或rollback 後,ResultSet 被關閉。
須要注意的地方:
Oracle 只支持HOLD_CURSORS_OVER_COMMIT 。
當Statement 執行下一個查詢,生成第二個ResultSet 時,第一個ResultSet 會被關閉,這和是否支持支持HOLD_CURSORS_OVER_COMMIT 無關。
不一樣的數據庫版本及 JDBC 驅動版本,對 ResultSet 的各類高級特性的支持是不同的,咱們能夠經過如下方法,來驗證具體的數據庫及 JDBC 驅動,是否支持 ResultSet 的各類特性。
DatabaseMetaData dbMeta = conn.getMetaData();
而後調用 DatabaseMetaData 對象的如下方法:
boolean supportsResultSetType(int resultSetType); boolean supportsResultSetConcurrency(int type, int concurrency); boolean supportsResultSetHoldability(int holdability);
看java doc是如何解釋的:
/** * Gives the JDBC driver a hint as to the number of rows that should * be fetched from the database when more rows are needed for this * <code>ResultSet</code> object. * If the fetch size specified is zero, the JDBC driver * ignores the value and is free to make its own best guess as to what * the fetch size should be. The default value is set by the * <code>Statement</code> object * that created the result set. The fetch size may be changed at any time. * * @param rows the number of rows to fetch * @exception SQLException if a database access error occurs; this method * is called on a closed result set or the * condition {@code rows >= 0} is not satisfied * @since 1.2 * @see #getFetchSize */ void setFetchSize(int rows) throws SQLException;
* Gives the JDBC driver a hint as to the number of rows that should
* be fetched from the database when more rows are needed for this
* <code>ResultSet</code> object.
* If the fetch size specified is zero, the JDBC driver
* ignores the value and is free to make its own best guess as to what
* the fetch size should be. The default value is set by the
* <code>Statement</code> object
* that created the result set. The fetch size may be changed at any time.
個人理解是當設置了fetchSize時,假設如今有100條數據,如今fetchSize=20,那麼當ResultSet.TYPE_FORWARD_ONLY時,你經過以下的方式訪問數據:
ResultSet rs = st.executeQuery(sql); // 執行sql查詢語句,返回查詢數據的結果集 System.out.println("最後的查詢結果爲:"); while (rs.next()) { // 判斷是否還有下一個數據 // 根據字段名獲取相應的值 String first_name = rs.getString("first_name"); String last_name = rs.getString("last_name"); // 輸出查到的記錄的各個字段的值 System.out.println("first_name=" + first_name + " " + "last_name=" + last_name); }
那麼每次獲取數據的條數就是20,那麼五次就能夠把所有數據拿到。可是若是fetchSize是0,那麼每循環一次就要從數據庫獲取一次數據,這個查詢過程要在循環100次後結束。。
同時,在這個查詢過程當中數據庫服務器的資源一直被這個查詢佔用中,浪費了服務器資源。
關於mysql客戶端和服務器如何通訊的過程請看該文章:http://my.oschina.net/xinxingegeya/blog/343109
在Statement中也能夠設置fetchSize的大小,但會被ResultSet中的setFetchSize覆蓋。
/** * Gives the JDBC driver a hint as to the number of rows that should * be fetched from the database when more rows are needed for * <code>ResultSet</code> objects generated by this <code>Statement</code>. * If the value specified is zero, then the hint is ignored. * The default value is zero. * * @param rows the number of rows to fetch * @exception SQLException if a database access error occurs, * this method is called on a closed <code>Statement</code> or the * condition {@code rows >= 0} is not satisfied. * @since 1.2 * @see #getFetchSize */ void setFetchSize(int rows) throws SQLException;
這裏的fetchSize和上面講的都是同一個道理。
這個java doc中對maxRows的描述
/** * Sets the limit for the maximum number of rows that any * <code>ResultSet</code> object generated by this <code>Statement</code> * object can contain to the given number. * If the limit is exceeded, the excess * rows are silently dropped. * * @param max the new max rows limit; zero means there is no limit * @exception SQLException if a database access error occurs, * this method is called on a closed <code>Statement</code> * or the condition {@code max >= 0} is not satisfied * @see #getMaxRows */ void setMaxRows(int max) throws SQLException;
* Sets the limit for the maximum number of rows that any
* <code>ResultSet</code> object generated by this <code>Statement</code>
* object can contain to the given number.
* If the limit is exceeded, the excess
* rows are silently dropped.
經過這個解釋能夠知道當sql中有limit的限制的時候,這個設置會silently dropped.
其實和limit的做用是同樣的。
可是maxRows和fetchSize的具體區別就要好好區分了
=============END=============