91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

用java怎么快速從系統報表頁面導出20w條數據

發布時間:2021-11-17 11:56:11 來源:億速云 閱讀:150 作者:iii 欄目:大數據

本篇內容介紹了“用java怎么快速從系統報表頁面導出20w條數據”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

先不談技術,先看效果,(完整案例代碼文末提供)

數據庫為mysql(理論上此套方案支持任何結構化數據庫),準備一張測試表t_person。表結構如下:

CREATE TABLE `t_person` (
  `id` bigint(20) NOT NULL auto_increment,
  `name` varchar(20) default NULL,
  `age` int(11) default NULL,
  `address` varchar(50) default NULL,
  `mobile` varchar(20) default NULL,
  `email` varchar(50) default NULL,
  `company` varchar(50) default NULL,
  `title` varchar(50) default NULL,
  `create_time` datetime default NULL,
  PRIMARY KEY  (`id`)
);

一共9個字段。我們先創建測試數據。

案例代碼提供了一個簡單的頁面,點以下按鈕一次性可以創建5w條測試數據:

用java怎么快速從系統報表頁面導出20w條數據

這里我連續點了4下,很快就生成了20w條數據,這里為了展示下數據的大致樣子,我直接跳轉到了最后一頁

用java怎么快速從系統報表頁面導出20w條數據

然后點開下載大容量文件,點擊執行執行按鈕,開始下載t_person這張表里的全部數據

用java怎么快速從系統報表頁面導出20w條數據

點擊執行按鈕之后,點下方刷新按鈕,可以看到一條異步下載記錄,狀態是P,表示pending狀態,不停刷新刷新按鈕,大概幾秒后,這一條記錄就變成S狀態了,表示Success

用java怎么快速從系統報表頁面導出20w條數據

然后你就可以下載到本地,文件大小大概31M左右

用java怎么快速從系統報表頁面導出20w條數據

看到這里,很多童鞋要疑惑了,這下載下來是csv?csv其實是文本文件,用excel打開會丟失格式和精度。這解決不了問題啊,我們要excel格式啊!!

其實稍微會一點excel技巧的童鞋,可以利用excel導入數據這個功能,數據->導入數據,根據提示一步步,當中只要選擇逗號分隔就可以了,關鍵列可以定義格式,10秒就能完成數據的導入

用java怎么快速從系統報表頁面導出20w條數據

你只要告訴運營小姐姐,根據這個步驟來完成excel的導入就可以了。而且下載過的文件,還可以反復下。

是不是從本質上解決了下載大容量數據集的問題?

原理和核心代碼

學弟聽到這里,很興奮的說,這套方案能解決我這里的痛點。快和我說說原理。

其實這套方案核心很簡單,只源于一個知識點,活用JdbcTemplate的這個接口:

@Override
public void query(String sql, @Nullable Object[] args, RowCallbackHandler rch) throws DataAccessException {
  query(sql, newArgPreparedStatementSetter(args), rch);
}

sql就是select * from t_personRowCallbackHandler這個回調接口是指每一條數據遍歷后要執行的回調函數。現在貼出我自己的RowCallbackHandler的實現

private class CsvRowCallbackHandler implements RowCallbackHandler{

    private PrintWriter pw;

    public CsvRowCallbackHandler(PrintWriter pw){
        this.pw = pw;
    }

    public void processRow(ResultSet rs) throws SQLException {
        if (rs.isFirst()){
            rs.setFetchSize(500);
            for (int i = 0; i < rs.getMetaData().getColumnCount(); i++){
                if (i == rs.getMetaData().getColumnCount() - 1){
                    this.writeToFile(pw, rs.getMetaData().getColumnName(i+1), true);
                }else{
                    this.writeToFile(pw, rs.getMetaData().getColumnName(i+1), false);
                }
            }
        }else{
            for (int i = 0; i < rs.getMetaData().getColumnCount(); i++){
                if (i == rs.getMetaData().getColumnCount() - 1){
                    this.writeToFile(pw, rs.getObject(i+1), true);
                }else{
                    this.writeToFile(pw, rs.getObject(i+1), false);
                }
            }
        }
        pw.println();
    }

    private void writeToFile(PrintWriter pw, Object valueObj, boolean isLineEnd){
        ...
    }
}

這個CsvRowCallbackHandler做的事就是每次從數據庫取出500條,然后寫入服務器上的本地文件中,這樣,無論你這條sql查出來是20w條還是100w條,內存理論上只占用500條數據的存儲空間。等文件寫完了,我們要做的,只是從服務器把這個生成好的文件download到本地就可以了。

因為內存中不斷刷新的只有500條數據的容量,所以,即便多線程下載的環境下。內存也不會因此而溢出。這樣,完美解決了多人下載的場景。

當然,太多并行下載雖然不會對內存造成溢出,但是會大量占用IO資源。為此,我們還是要控制下多線程并行的數量,可以用線程池來提交作業

ExecutorService threadPool = Executors.newFixedThreadPool(5);

threadPool.submit(new Thread(){
	@Override
	public void run() {
    下載大數據集代碼
  }
}

最后測試了下50w這樣子的person數據的下載,大概耗時9秒,100w的person數據,耗時19秒。這樣子的下載效率,應該可以滿足大部分公司的報表導出需求吧。

“用java怎么快速從系統報表頁面導出20w條數據”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

玉龙| 恭城| 丰顺县| 淮安市| 萍乡市| 长汀县| 横峰县| 全南县| 宕昌县| 临洮县| 开化县| 台湾省| 舞钢市| 竹北市| 勃利县| 留坝县| 乐亭县| 茌平县| 镇远县| 肥乡县| 吉首市| 轮台县| 兴和县| 湖北省| 修文县| 江口县| 温泉县| 香格里拉县| 双鸭山市| 来凤县| 漳浦县| 金溪县| 界首市| 义乌市| 贡觉县| 马鞍山市| 宝山区| 英吉沙县| 台山市| 黔南| 林西县|