대용량의 데이터를 데이터베이스에서 읽어 Excel로 다운로드 할 때 OOM(Out Of Memory)가 자주 발생한다.
OOM을 해결하기 위해서 Mybatis를 사용하는 경우에는 ResultHandler를 이용하여 각각의 Result에 대해 Excel의 Row를 생성하면 OOM 발생을 방지할 수 있다.
(기존의 DAO를 사용하지 않는 이유는 ResultHandler를 사용해서 데이터베이스에서 행을 패치하면서 바로 엑셀 생성을 처리하기 위해서임)
SqlSession session = sqlSessionFactory.openSession();
ResultHandler 를 이용하여 row별로 처리할때는 첫번째로 session을 열어줘야한다.
class InnerResultHandler implements ResultHandler {
@Override
public void handleResult(ResultContext resultContext) {
Map data = new HashMap();
try {
Object obj = (Object) resultContext.getResultObject();
Field[] fields = obj.getClass().getDeclaredFields(); // reflect 써서 entity => hashMap 변경
for(int i=0; i<=fields.length-1;i++){
fields[i].setAccessible(true);
data.put(fields[i].getName(), fields[i].get(obj));
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
try {
session.select(pkgId, param, new InnerResultHandler());
} catch(Exception e) {
logger.error("Sql Session Exception : {}", e);
} finally {
session.close();
}
따로 Class를 만들어도 되지만 지금은 Inner Class로 빼는게 보기에도 직관적이어서 위 처럼 하였다.
아래는 엑셀 완성본이다.
public void exportExcel(HttpServletResponse response, Map param, String pkgId, int workbookNum) {
CreateExcelWrapper excel = new CreateExcelWrapper();
try {
excel.init( response, workbookNum, fileName, sField, sHeaderName, loginId, excelPath);
excel.open();
excel.createSheet();
SqlSession session = sqlSessionFactory.openSession();
class InnerResultHandler implements ResultHandler {
@Override
public void handleResult(ResultContext resultContext) {
Map data = new HashMap();
try {
Object obj = (Object) resultContext.getResultObject();
Field[] fields = obj.getClass().getDeclaredFields(); // reflect 써서 entity => hashMap 변경
for(int i=0; i<=fields.length-1;i++){
fields[i].setAccessible(true);
data.put(fields[i].getName(), fields[i].get(obj));
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
excel.createBody(data);
}
}
try {
session.select(pkgId, param, new InnerResultHandler());
} catch(Exception e) {
logger.error("Sql Session Exception : {}", e);
} finally {
session.close();
}
} catch(Exception e) {
logger.error("Create Excel Wrapper Exception : {}", e);
} finally {
excel.close();
logger.info("Excel End ==========================");
}
}
'Java' 카테고리의 다른 글
JWT 검증 (0) | 2022.04.19 |
---|---|
File Upload (0) | 2022.02.07 |
Menu Children 만들기 (0) | 2019.10.17 |
Lombok 설치하기 (0) | 2019.06.20 |