使用Java IO將數據導出到文本

一、需求背景

公司爲了對接某數據分析產品A(縮寫是YGFZ),需要將數據庫訂單數據按照A公司格式要求導出到txt文本,然後才能進一步導入到A產品中進行數據分析。

其中要求的格式爲:每行有10個訂單數據,每個數據爲Json字符串格式,也就是每行是一個JsonArray,每個JsonArray有10個元素。

二、分析

目前訂單是千萬級數據庫,每個表10G左右,不可能一次全部查出來,然後在分割成10個10個一組。

那麼,這裏首先根據下單時間查詢,按年份輸出。比如2018年數據,先查出總數據條數,這個速度很快,三百萬數量3秒以內。這三百萬數據也是很龐大,然後分頁查詢,比如每次查詢10萬條,然後把這10萬條組成的ArrayList分割成10個10個小的ArrayList。

// 分割的數組包含fromIndex,不包含toIndex
List<E> subList(int fromIndex, int toIndex);

接下來,先把這些分割好的list放到一個Map中存儲備用。

然後,就開始執行文本輸出操作相關了,新建輸出流

    // 根據時間年月日時分秒定義文件名稱
    String strDate = DateUtils.formatDate2Str(new Date(), DateUtils.DATE_TIME_PATTON_3);
    String fileName = "D:\\" + strDate + ".txt";
    File f = new File(fileName);
    BufferedWriter bw = new BufferedWriter(new FileWriter(f));
    // 如果文件不存在,新建文件
    if (!f.exists()) {
        f.createNewFile();
    }

然後,遍歷剛纔存儲數據的Map,將數據轉爲JsonArray(fastJson)輸出到文件。

// 遍歷map,把每10個訂單數據一行行輸出到文件
Set<Map.Entry<String, Object>> entries = map.entrySet();
for (Map.Entry<String, Object> entry : entries) {
    Object value = entry.getValue();
    // 轉爲fast JsonArray
    JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(value));
    logger.info(jsonArray.toString());
    bw.write(jsonArray.toString());
    // 換行
    bw.write("\r\n");
    bw.flush();
}

三、測試

在對測試庫3萬多數據進行測試時,生成的文件如下:
在這裏插入圖片描述
不同分頁條數時用時如下:

分頁條數 用時(ms)
1000 15061
5000 10228
10000 9018
50000 8824

由於測試庫一共3萬多條數據,所以分頁5萬10萬沒什麼區別。在數據量大的時候分頁數據越大,則數據連接關閉的次數越少,此間耗時也降低。千萬級數據庫,對內存使用很大,所以在分頁條數也應有所取捨。

四、代碼

public String getOrderDataWriteToTxt(String startTime, String endTime, Integer pageSize) {
    String uuid = UUID.randomUUID().toString();
    String result = "";
    logger.info("getOrderDataWriteToTxt 接收請求:" + uuid + "參數: startTime = " + startTime + ",endTime = " + endTime);
    try {
        if (StringUtils.isEmpty(startTime) || StringUtils.isEmpty(endTime)) {
            result = ResultUtil.createFailureResult("-10000", "參數有誤!");
            return result;
        }
        HashMap<String, Object> paramMap = new HashMap<>();
        paramMap.put("saleTimeStart", DataUtil.sdcFormatDateStrToPad(startTime, true));
        paramMap.put("saleTimeEnd", DataUtil.sdcFormatDateStrToPad(endTime, false));
        // 每次從數據庫最多查詢多少條數據
        if (pageSize == null) {
            pageSize = 1000 * 10;
        }
        if (pageSize % 10 != 0 || pageSize < 10) {
            result = ResultUtil.createFailureResult("-20000", "分頁參數不合理!");
            return result;
        }
        // 查詢在規定時間內數據總條數
        int count = orderMapper.selectOrderCountToYiGuan(paramMap);
        // 一共能查多少頁
        int pageCount = (count % pageSize == 0) ? count / pageSize : (count / pageSize + 1);
        // 根據時間年月日時分秒定義文件名稱
        String strDate = DateUtils.formatDate2Str(new Date(), DateUtils.DATE_TIME_PATTON_3);
        String fileName = "D:\\" + strDate + ".txt";
        File f = new File(fileName);
        BufferedWriter bw = new BufferedWriter(new FileWriter(f));
        // 如果文件不存在,新建文件
        if (!f.exists()) {
            f.createNewFile();
        }
        HashMap<String, Object> map = new HashMap<>();
        // 分批次查詢數據庫
        for (int j = 0; j < pageCount; j++) {
            paramMap.put("start", j * pageSize);
            paramMap.put("limit", pageSize);
            // 查詢訂單數據
            List<OrderNew> orderList = orderMapper.selectOrderToYiGuan(paramMap);
            // 輸出每行10個
            int line = 10;
            int size = orderList.size();
            // 一共有多少行
            int a = (size % line == 0) ? size / line : (size / line + 1);
            for (int i = 0; i < a; i++) {
                // 將獲取到的訂單列表每十個一組放入map中備用
                // subList(int fromIndex, int toIndex) 包含fromIndex,不包含toIndex
                map.put("list" + i, orderList.subList(i * line, line * (i + 1) > size ? size : line * (i + 1)));
            }
            // 遍歷map,把每10個訂單數據一行行輸出到文件
            Set<Map.Entry<String, Object>> entries = map.entrySet();
            for (Map.Entry<String, Object> entry : entries) {
                Object value = entry.getValue();
                // 轉爲fast JsonArray
                JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(value));
                logger.info(jsonArray.toString());
                bw.write(jsonArray.toString());
                // 換行
                bw.write("\r\n");
                bw.flush();
            }
            map.clear();
        }
        bw.close();
        result = ResultUtil.createSuccessResult();
    } catch (IOException e) {
        e.printStackTrace();
        result = ResultUtil.createFailureResult(e);
    }
    return result;
}

以上代碼所使用的工具類(略)。

微信公衆號

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章