Oracle로 작성한 쿼리를 Mysql로 바꾸고 테스트 코드를 작성해보자
<![CDATA[SELECT B.num, B.title, B.writer, B.updatedate
FROM(
SELECT ROWNUM as rn, A.num, A.title, A.writer, A.updatedate
FROM (
SELECT * FROM board
WHERE type=#{type} AND title LIKE '%'||#{cri.keyword}||'%' ORDER BY num DESC) A
WHERE rownum <=#{cri.pageNum} * #{cri.amount}) B
WHERE rn>(#{cri.pageNum}-1) * #{cri.amount}]]>
SELECT B.num, B.title, B.writer, B.updatedate FROM(
SELECT *
FROM board
WHERE type='faq'
order by num asc
)B
LIMIT 10,10;
페이징 검색하다가 커서를 이용하는게 장점이 있다고 해서 이걸로도 구현해봤다. controller까지만..ㅎㅎ
커서로 구현한다길래 정말 "커서"를 사용하는 줄 알고 커서까지 찾아봤는데 다른거였다.
<select id="getListWithPagingCursor" resultMap="board" parameterType="java.util.HashMap">
SELECT * FROM board
WHERE type=#{type}
AND title LIKE concat('%', #{cri.keyword},'%')
<if test= "cri.cursorId != null">
<![CDATA[AND num < #{cri.cursorId}]]>
</if>
order by num desc
LIMIT #{cri.amount}
</select>
@Test
@DisplayName("두번째로 조회하는 페이지의 id는 첫번째의 id보다 작다.")
public void getListWithPagingCursor() {
//given
//cursorID가 null일 때(첫번쨰 조회)
Criteria cri1 = new Criteria();
HashMap<String, Object> map1 = new HashMap<>();
map1.put("type", "faq");
map1.put("cri", cri1);
List<Board> firstPaging = boardMapper.getListWithPagingCursor(map1);
Integer cursorId = firstPaging.get(9).getNum(); //제일 마지막으로 가져온 id를 cursorId로 설정
log.info("cursorId: {}", String.valueOf(cursorId));
//cursorID가 전해질떄(두번쨰 이상 조회)
Criteria cri2 = new Criteria();
cri2.setCursorId(cursorId);
HashMap<String, Object> map2 = new HashMap<>();
map2.put("type", "faq");
map2.put("cri", cri2);
//when
List<Board> secondPaging = boardMapper.getListWithPagingCursor(map2);
//then //뭘로 확인하지....
Assertions.assertThat(secondPaging.get(0).getNum()).isLessThan(firstPaging.get(9).getNum());
}
뭔가 given/when/then 나누기가 너무 어려운데,,, 테스트 코드를 어떻게 짜야 잘짰다고 소문이 날까...
정말 커서를 쓰는줄 알고 알아본것들ㅎㅎㅎ
함수는 쿼리를 수행한 후 값을 가져오는 것이 중점이지만
프로시저는 여러 쿼리를 한번에 수행하는 것이 중점이다.
프로시저를 생성하가에 앞서 MYSQL에 프로시저 생성 권한을 줬는지 확인하고 Create Stored Procedure를 눌러 프로시저를 생성해 준다.
CREATE PROCEDURE '[프로시저명]' (
[파라미터명1] VARCHAR(20) --파라미터 선언
, [파라미터명2] INTEGER
)
BEGIN
DECLARE [변수명1] INTEGER --변수명
SELECT COUNT(*) + 1
INTO [변수명1] --변수에 값 할당
FROM [테이블 명];
INSERT INTO [테이블명](NUM, NAME, AGE) VALUES(변수명1, [값], [값])
END
호출하는 방법은 CALL [프로시저명]([파라미터1], [파라미터1]); --프로시저 실행
FROM -> WHERE -> GROUP BY -> HAVING -> SELECT -> ORDER BY