jdbc和mybatis的流式查詢(xún)使用方法
導(dǎo)語(yǔ):
有些時(shí)候我們所需要查詢(xún)的數(shù)據(jù)量比較大,但是jvm內(nèi)存又是有限制的,數(shù)據(jù)量過(guò)大會(huì)導(dǎo)致內(nèi)存溢出。這個(gè)時(shí)候就可以使用流式查詢(xún),數(shù)據(jù)一條條的返回,處理完一條在拿下一條數(shù)據(jù),這樣每次在內(nèi)存里面的數(shù)據(jù)其實(shí)很小,不會(huì)導(dǎo)致內(nèi)存溢出。
本文里面會(huì)講到j(luò)dbc的流式查詢(xún)和mybatis的流式查詢(xún)。
jdbc流式查詢(xún):
jdbc的流式查詢(xún)需要在生成PreparedStatement的時(shí)候設(shè)置三個(gè)參數(shù)。如下:
PreparedStatement stmt = jdbcTemplate.getDataSource().getConnection().prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); stmt.setFetchSize(Integer.MIN_VALUE);
主要使用到的是java.sql.Connection的prepareStatement方法。
PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException;
resultSetType和resultSetConcurrency我們要分別設(shè)置為ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY。
還有就是fetchSize設(shè)置為Integer.MIN_VALUE,一開(kāi)始比較疑惑為啥是這個(gè)值。后來(lái)發(fā)現(xiàn)代碼里面對(duì)這個(gè)值其實(shí)是有特殊處理的。
這個(gè)是com.mysql.cj.jdbc.StatementImpl的setFetchSize方法。
@Override public void setFetchSize(int rows) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { if (((rows < 0) && (rows != Integer.MIN_VALUE)) || ((this.maxRows > 0) && (rows > this.getMaxRows()))) { throw SQLError.createSQLException(Messages.getString("Statement.7"), MysqlErrorNumbers.SQL_STATE_ILLcom.mysql.cj.jdbc.StatementImpl的方法EGAL_ARGUMENT, getExceptionInterceptor()); } this.query.setResultFetchSize(rows); } }
resultSetType,有以下三種
/** * The constant indicating the type for a <code>ResultSet</code> object * whose cursor may move only forward. * @since 1.2 */ int TYPE_FORWARD_ONLY = 1003; /** * The constant indicating the type for a <code>ResultSet</code> object * that is scrollable but generally not sensitive to changes to the data * that underlies the <code>ResultSet</code>. * @since 1.2 */ int TYPE_SCROLL_INSENSITIVE = 1004; /** * The constant indicating the type for a <code>ResultSet</code> object * that is scrollable and generally sensitive to changes to the data * that underlies the <code>ResultSet</code>. * @since 1.2 */ int TYPE_SCROLL_SENSITIVE = 1005;
stmt = conn.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); stmt.setFetchSize(Integer.MIN_VALUE);
resultSetConcurrency有以下兩種,流式查詢(xún)要設(shè)置為只讀的,數(shù)據(jù)不會(huì)被更新。
/** * The constant indicating the concurrency mode for a * <code>ResultSet</code> object that may NOT be updated. * @since 1.2 */ int CONCUR_READ_ONLY = 1007; /** * The constant indicating the concurrency mode for a * <code>ResultSet</code> object that may be updated. * @since 1.2 */ int CONCUR_UPDATABLE = 1008;
mybatis流式查詢(xún):
mapper中的代碼:
@Select("select * from xxx order by xx desc") @Options(resultSetType = ResultSetType.FORWARD_ONLY, fetchSize = Integer.MIN_VALUE) @ResultType(XxxObject.class) void queryStreamResult(ResultHandler<XxxObject> handler);
在查詢(xún)方法上加入注解@Options和@ResultType。設(shè)置參數(shù)不用多說(shuō)和上面jdbc的底層是一樣的,參數(shù)值也一樣。
只不過(guò)設(shè)置了@ResultType告訴程序應(yīng)該要返回什么類(lèi)型的對(duì)象。還有這個(gè)ResultHandler其實(shí)就是Consumer的函數(shù)式接口用來(lái)處理每一條返回的數(shù)據(jù)。
具體方法中的代碼:
@Override public Boolean dealDataList() { mapper.queryStreamResult(resultContext -> { dealSingleData(resultContext.getResultObject().getUid()); }); return true; }
這里怎么使用每一條返回的數(shù)據(jù)只要在resultContext使用ResultObject就可以拿到上面mapper設(shè)置的XxxObject對(duì)象進(jìn)行操作了。
到此這篇關(guān)于jdbc和mybatis的流式查詢(xún)使用方法的文章就介紹到這了,更多相關(guān)jdbc和mybatis流式查詢(xún)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot項(xiàng)目實(shí)現(xiàn)MyBatis流式查詢(xún)的教程詳解
- 詳解mybatis流式查詢(xún)與分頁(yè)插件
- Mybatis Plus中的流式查詢(xún)案例
- MyBatis流式查詢(xún)的使用詳解
- MyBatis流式查詢(xún)的項(xiàng)目實(shí)踐
- 擴(kuò)展tk.mybatis的流式查詢(xún)功能實(shí)現(xiàn)
- MyBatis流式查詢(xún)的三種實(shí)現(xiàn)方法
- MyBatis如何實(shí)現(xiàn)流式查詢(xún)的示例代碼
- Mybatis中流式查詢(xún)的實(shí)現(xiàn)示例
相關(guān)文章
java多次嵌套循環(huán)查詢(xún)數(shù)據(jù)庫(kù)導(dǎo)致代碼中數(shù)據(jù)處理慢的解決
這篇文章主要介紹了java多次嵌套循環(huán)查詢(xún)數(shù)據(jù)庫(kù)導(dǎo)致代碼中數(shù)據(jù)處理慢的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03mybatis-plus分頁(yè)查詢(xún)?nèi)N方法小結(jié)
本文主要介紹了mybatis-plus分頁(yè)查詢(xún)?nèi)N方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05java隊(duì)列實(shí)現(xiàn)方法(順序隊(duì)列,鏈?zhǔn)疥?duì)列,循環(huán)隊(duì)列)
下面小編就為大家分享一篇java隊(duì)列實(shí)現(xiàn)方法(順序隊(duì)列,鏈?zhǔn)疥?duì)列,循環(huán)隊(duì)列),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2017-12-12Java隨手筆記8之包、環(huán)境變量和訪問(wèn)控制及maven profile實(shí)現(xiàn)多環(huán)境打包
這篇文章主要介紹了Java隨手筆記8之包、環(huán)境變量和訪問(wèn)控制及maven profile實(shí)現(xiàn)多環(huán)境打包的相關(guān)資料,需要的朋友可以參考下2015-11-11springboot結(jié)合maven配置不同環(huán)境的profile方式
這篇文章主要介紹了springboot結(jié)合maven配置不同環(huán)境的profile方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01程序包org.springframework.boot不存在的問(wèn)題解決
本文主要介紹了程序包org.springframework.boot不存在的問(wèn)題解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-09-09