Mybatis > RowBounds 의 고찰

2016. 8. 9. 09:36framework/MyBatis


 

Mybatis > RowBounds 의 고찰

 


리스트의 페이징(Paging)을 보던 중 처음보는 클래스를 발견했다.

RowBounds 클래스이다.

사용하는 곳을 본적이 없어서 이번에 처음 보게 되었다.

페이징은 보통 쿼리에서 해결하곤 했다.

크거나 같다 (>= <=) , between 등을 이용해서...

 

그런데 RowBounds 클래스가 페이징을 해준다는 것이다.

파라미터로 가져오고 싶은 구간을 넘겨주면 그 구간의 데이터를 리턴한다는 것이다.

바로 API를 뒤져봤다.

 



 

다음은 Mybatis API에서 발췌한 정보이다. ( 출처 )

마지막으로 리턴되는 데이터의 범위를 제한하거나 결과를 핸들링 하는 로직을 부여할 수 있는 3개의 select 메소드가 있다.

 

1
2
3
4
5
<E> List<E> selectList (String statement, Object parameter, RowBounds rowBounds)
<K,V> Map<K,V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowbounds)
void select (String statement, Object parameter, ResultHandler<T> handler)
void select (String statement, Object parameter, RowBounds rowBounds, ResultHandler<T> handler)
 
cs

 


RowBounds 파라미터는 마이바티스로 하여금 특정 개수 만큼의 레코드를 건너띄게 한다. RowBounds클래스는 offsetlimit 둘다 가지는 생성자가 있다.

1
2
3
 int offset = 100;
 int limit = 25;
 RowBounds rowBounds = new RowBounds(offset, limit); 
cs


가장 좋은 성능을 위해 결과셋의 타입을 SCROLL_SENSITIVE나 SCROLL_INSENSITIVE로 사용하라.

ResultHandler파라미터는 레코드별로 다룰수 있도록 해준다. List에 추가할수도 있고 Map, Set을 만들수도 있으며 각각의 결과를 그냥 던질수도 있다. ResultHandler로 많은 것을 할 수 있고 마이바티스는 결과셋을 다루기 위해 내부적으로 사용한다.

 

인터페이스는 매우 간단하다.

1
2
3
4
 package org.apache.ibatis.session;
 public interface ResultHandler<T> {
   void handleResult(ResultContext<extends T> context);
 }
cs

이런 내용이다.

 

읽어보면 offset 만큼 건너띄고 limit 만큼 가져온다 라고 해석된다.


여기서 몇가지 의문점이 생겼다.

어떤 방식으로 페이징처럼 처리되는지 궁금했다.

예를들면 컬랙션을 이용하여 특정 구간을 잘라서 처리하는지 쿼리를 변조해서 처리하는지 궁금했다.

성능도 어느정도일지 궁금했다.

 


그래서 200만건 데이터를 가지고 테스트 해보았다.

먼저 보통의 페이징 기법(Paging Query)과 비교했다.

 


페이지는 10개씩 보여주도록 했다.

결과는 신기했다.

 

일단 RowBounds 클래스를 사용했을 때 Log4j에 찍히는 쿼리의 변화는 없었다.

그말인 즉슨 XML에 정의된 쿼리 그대로 console에 출력됐다.

 

하지만 데이터는 계속 offset + limit 갯수만큼 가져왔다.

 

소스를 까보면 어떻게 처리될지 알 수 있겠지만...

 

일단은 그냥넘어갔다.

 

다음 표를 보자.

페이지에 따른 조회된 데이터 갯수를 정리해 보았다.

(소스를 까보지 않았으니 Log4j 로 출력되는 데이터 결과값 기준으로 작성)

 

 

 페이징 기법(Pagin Query)

 RowBounds

 1 페이지 ( 1 ~ 10 )

 10건 조회

 10건 조회

 2 페이지 ( 11 ~ 20 )

 10건 조회

 20개 조회 후 10번째 부터 10건

 3 페이지 ( 21 ~ 30 )

 10건 조회

 30개 조회 후 20번째 부터 10건

.

.

.

 

 10 페이지 ( 91 ~ 100 )

 10건 조회

 100개 조회 후 90번째 부터 10건

 

 

 



더이상의 테스트는 의미없다.

 

마지막 페이지를 눌렀다가 서버를 강제종료했다.

 

RowBounds 는 소량의 데이터에서 필요한 구간을 가져올 경우 엄청나게 효율적이라고 판단된다.

 

소스도 깔끔하니 보기 좋다.

 

하지만 건너띄어야 할 데이터를 모두 가져온다는 함정이 있다.

 

이는 건너띄어야 할 데이터가 많으면 많을수록 불리하다.

 

속도 역시 너무 좋지 않았다.

 

 

 

결론적으로 RowBounds 클래스 원리와 특성을 알고 난 후 적절한 상황 (소량의 데이터이며 증가할 여지가 없는 등 ?) 에서의 사용은 긍정적이다.

그러나 그렇지 않은 경우에는 완전히 배제하는 것을 추천한다.