Mybatis Interceptor 자동 Paging처리 만들기(1) 바로가기
⚫Interceptors
PrepareInterceptor
@Override
public Object intercept(Invocation invocation) throws Throwable {
try {
StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
MetaObject metaStatementHandler = MetaObject.forObject(statementHandler,
DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY, DEFAULT_REFLECTOR_FACTORY);
PageInfo pageInfo = (PageInfo) metaStatementHandler.getValue("delegate.rowBounds");
String originalSql = (String) metaStatementHandler.getValue("delegate.boundSql.sql");
// limit 추가된 query
metaStatementHandler.setValue("delegate.boundSql.sql", attachQuery(originalSql, pageInfo));
} catch (ClassCastException e) {}
return invocation.proceed();
}
PrepareInterceptor가 하는일은 추가적으로 Custom하게 Query를 붙이는 것이다.
- 기본적으로 PageInfo를 상속받은 매개변수가 들어오는지 판단
- 있으면 attachQuery를 통해서 알맞는 Query 추가
private String attachQuery(String originalSql, PageInfo pageInfo) {
if (pageInfo.getTotalCount() == -1)
return attachCountQuery(originalSql, pageInfo);
if (!isNullPageInfo(pageInfo))
return attachLimitQuery(originalSql, pageInfo);
return originalSql;
}
- totalCount가 -1이면 아직 Count Query를 날리지 않았다고 판단하고 CountQuery를 붙임
private String attachCountQuery(String originalSql, PageInfo pageInfo) {
StringBuilder sb = new StringBuilder("SELECT COUNT(*) FROM ( ");
sb.append(originalSql);
sb.append(" ) COUNT_TABLE ");
String attachedCountQuery = sb.toString();
return attachedCountQuery;
}
Wrapper 형식으로 감싸서 Count Query 생성
2. totalCount에 값이 등록되었고, page, size가 존재하면 LIMIT 을 적용시킨 Query 붙임
private String attachLimitQuery(String originalSql, PageInfo pageInfo) {
StringBuilder sb = new StringBuilder(originalSql);
sb.append(" LIMIT ");
sb.append((pageInfo.getPage() - 1) * pageInfo.getSize());
sb.append(", ");
sb.append(pageInfo.getSize());
String attachLimitQuery = sb.toString();
return attachLimitQuery;
}
마무리
최종적으로는 다음과같은 순서로 프로세스가 진행된다.
[mapper method 호출]
→ [QueryInterceptor(totalCount)]
→ [PrepareInterceptor(totalCount)]
→ [totalCount반환]→ [QueryInterceptor(list)]
→ [PrepareInterceptor(list)]
→ [list반환]→ [list, totalCount로 PagableResponse 생성하여 반환]
Uploaded by Notion2Tistory v1.1.0