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=============