VanillaSky7 2023. 5. 10. 20:48

검색 기능 구현 시 고려사항


 

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>