2026년 1월 13일 화요일

resulthandler 사용방식

 import org.apache.ibatis.session.ResultContext;

import org.apache.ibatis.session.ResultHandler;

import org.apache.ibatis.session.SqlSession;

import java.io.*;

import java.nio.charset.StandardCharsets;

import java.util.ArrayList;

import java.util.List;

import java.util.Map;


public class LargeDataExportService {


    private SqlSessionFactory sqlSessionFactory;


    public void exportDataWithBatch(String filePath) {

        // 1. 파일 초기화 (기존 파일이 있으면 덮어쓰기 위해 false, 이후 true로 append)

        try (SqlSession session = sqlSessionFactory.openSession()) {

            

            // MyBatis ResultHandler 구현

            session.select("com.example.mapper.ProductMapper.selectLargeData", new ResultHandler<Map<String, Object>>() {

                private final List<Map<String, Object>> batchList = new ArrayList<>(1000);

                private boolean isFirstWrite = true;


                @Override

                public void handleResult(ResultContext<? extends Map<String, Object>> resultContext) {

                    batchList.add(resultContext.getResultObject());


                    // 1,000건이 쌓이면 파일에 씀

                    if (batchList.size() >= 1000) {

                        flushBatch(batchList, filePath, !isFirstWrite);

                        isFirstWrite = false;

                        batchList.clear();

                    }

                }

                

                // 마지막에 남은 데이터 처리 (예: 1000건이 안 되는 나머지)

                public void flushRemaining() {

                    if (!batchList.isEmpty()) {

                        flushBatch(batchList, filePath, !isFirstWrite);

                    }

                }

            });

            

        } catch (Exception e) {

            e.printStackTrace();

        }

    }


    private void flushBatch(List<Map<String, Object>> data, String filePath, boolean append) {

        // 2. BufferedWriter의 append 모드 활용

        try (FileOutputStream fos = new FileOutputStream(filePath, append);

             OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8);

             BufferedWriter writer = new BufferedWriter(osw)) {


            for (Map<String, Object> row : data) {

                // 가공 로직 (압축 등) 수행 후 쓰기

                String processedLine = processRow(row); 

                writer.write(processedLine);

                writer.newLine();

            }

            writer.flush();

        } catch (IOException e) {

            throw new RuntimeException("파일 쓰기 중 오류 발생", e);

        }

    }


    private String processRow(Map<String, Object> row) {

        // 여기서 아까 논의한 Zstd/LZ4 압축 로직을 넣으시면 됩니다.

        return row.get("ID").toString() + "," + row.get("NAME").toString();

    }

}


댓글 없음: