3. 게시판 검색 기능
검색 기능 구현 시 고려사항
1. 동적쿼리 → 검색할 대상을 무엇으로 선택하느냐에 따라 쿼리가 달라져야 한다. (검색 선택 옵션이 제목+내용, 제목만, 작성자에 따른 동적으로 쿼리 구성 고려)
2. 페이지 이동 처리 → 검색한 게시물을 읽고 '목록' 버튼을 눌렀을 때 다시 boardList.jsp로 돌아오는 처리를 해주어야 한다.
MyBatis 동적 쿼리들
① <sql>과 <include>
→ 아래 예제 코드와 같이 공통 부분을 <sql>로 정의하고, <include>로 포함시켜 재사용한다.
<sql id="selectFromBoard">
SELECT bno, title, content, writer, view_cnt, comment_cnt, reg_date
FROM board
</sql>
<select id="select" parameterType="int" resultType="BoardDto">
<include refid="selectFromBoard"/>
WHERE bno = #{bno}
</select>
② <if>, <choose>-<when>
<if>를 사용하게 되면 각 조건들이 전부 만족될 수 있는 경우가 있을 수 있으므로 한 가지 조건만을 만족하게 할 수 있는 방향으로 작성하기 위해서 아래 예제 코드와 같이 <choose>-<when> 코드를 사용한다.
(WHERE 뒤에 true를 붙어주어야 WHERE AND와 같이 문법 에러가 발생하지 않음)
<sql id="searchCondition">
<choose>
<when test='option=="T"'>
AND title LIKE concat('%', #{keyword}, '%')
</when>
<when test='option=="W"'>
AND writer LIKE concat('%', #{keyword}, '%')
</when>
<otherwise>
AND (title LIKE concat('%', #{keyword}, '%')
OR content LIKE concat('%', #{keyword}, '%'))
</otherwise>
</choose>
</sql>
T는 제목만, W는 작성자, otherwise의 경우 제목+내용에 대한 각 검색 옵션을 의미한다.
※ 이때, Oracle은 concat 함수를 생략할 수 있으나 MySQL은 써주어야 한다. 또 concat 함수에 포함되어 있는 %는 와일드카드를 의미한다. 예를 들어 'title%'라면 title 뒤의 여러 글자를 0개~n개까지를 포함할 수 있는데, 여기서 주의할 점은 0개를 포함하기 때문에 title 또한 해당된다는 것이다. 만약 MySQL에서 한 글자만을 포함하고 싶다면 '_'를 사용하고 이때 'title_'라면 title 뒤의 글자 1개를 포함할 수 있는데, 이때 title은 해당되지 않는다는 것에 주의한다. (Oracle의 경우 '?'를 사용)
③ <foreach>
WHERE bno IN (1, 2, 3)처럼 IN을 통해 여러 개를 다룰 때 <foreach>를 사용한다. 아래 예제 코드와 같이 배열로 받게 되면 () 안에 구분자(,)를 통해 만들어주게 되는 것이다.
<select id="getSelected" resultType="BoardDto">
SELECT bno, title, content, writer, view_cnt, comment_cnt, reg_date
FROM board
WHERE bno IN
<foreach collection="array" item="bno" open="(" close=")" separator=",">
#{bno}
</foreach>
ORDER BY reg_date DESC, bno DESC
</select>