一、前言
java 中MySQL JDBC 封裝了流式查詢操作,通過設置幾個參數,就可以避免一次返回數據過大導致 OOM。
二、如何使用
2.1 之前查詢
public void selectData(String sqlCmd) throws SQLException { validate(sqlCmd); Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try { conn = petadataSource.getConnection(); stmt = conn.prepareStatement(sqlCmd); rs = stmt.executeQuery(); try { while(rs.next()){ try { System.out.println("one:" + rs.getString(1) + "two:" + rs.getString(2) + "thrid:" + rs.getString(3)); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } finally { close(stmt, rs, conn); } }
2.2 現在流式查詢
public void selectData(String sqlCmd,) throws SQLException { validate(sqlCmd); Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try { conn = petadataSource.getConnection(); stmt = conn.prepareStatement(sqlCmd, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); stmt.setFetchSize(Integer.MIN_VALUE); rs = stmt.executeQuery(); try { while(rs.next()){ try { System.out.println("one:" + rs.getString(1) + "two:" + rs.getString(2) + "thrid:" + rs.getString(3)); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } finally { close(stmt, rs, conn); } }
可知只是prepareStatement時候改變了參數,並且設置了PreparedStatement的fetchsize為Integer.MIN_VALUE。三、 結果對比對於同一個sqlCmd,同一批數據,使用兩種方式占用內存對比如下:
-
非流式編程
image.png -
流式編程
image.png
另外非流式方式由於是把符合條件的數據一下子全部加在到內存,並且由於數據量比較大,需要mysql處理的時間比較長,我測試情況下需要一分鍾才會返回結果到內存(數據量比較大),然后才能通過數據集返回數據。
而流式方式是每次返回一個記錄到內存,所以占用內存開銷比較小,並且調用后會馬上可以訪問數據集的數據。
--------------
轉自
鏈接:https://www.jianshu.com/p/c1e6eeb71c74