jdbcTemplate讀數據內存溢出

最近做Hadoop項目的自動化測試,代碼要從hadoop mart裏讀數據出來,寫到.csv文件裏。有一個query結果集包含10萬+條記錄,且每條記錄包含30+個列,於是jdbcTemplate華麗麗的內存溢出了。其實論數據量,這個真心不算大…
仔細看了看代碼,大概知道了原因,結果集保存在List<Map<String, Object>>這種結構中,而Map是比較消耗內存的,10萬+個Map,每個Map30+對key-value…內存溢出是可以理解的

public List<Map<String, Object>> querySQL(final String query){
    return jdbcTemplate.queryForList(query);
}

於是改用最原始的statement執行query,設置fetch szie,然後將result set存到List<List<String>>中。每到2000行,就寫一次csv並將List<List<String>>清空,666,跑起來又快又不會溢出!

    public void readWriteResultSetTOCsv(String query, String csvPath){
        try (Connection con = jdbcTempalte.getDataSource.getConnection();
        Statement stmt = con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);){
            stmt.setFetchSize(5000);
            ResultSet rs = stmt.executeQuery(query);
            List<List<String>> rows = new ArrayList<>();
            List<String> header = getColHeaderFromRS(rs);
            while(rs.next()){
                List<String> row = new ArrayList<>();
                for(String h : header){
                    row.add(rs.getString(h));
                }
                rows.add(row);
                if(rows.size() > 2000){
                    //write to csv
                    rows.clear();
                }
            }
            if(rows.isEmpty()){
                //write to csv
            }
            rs.close();
        }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章