12.01. 책 검색 기능 추가하기 - 1

12.1. 책 검색 기능 개요

책 목록을 검색하기 위한 기능을 만든다.
목록 화면에서 검색어를 입력하고 검색 버튼 클릭하면 검색 주소로 이동한다. 검색 주소는 /list?keyword=검색어 형식이다.

12.2. 책 검색 쿼리 작성

기존의 책 목록 쿼리 select_list 를 수정해서 검색 기능을 추가한다.

src/main/resources/sqlmap/book_SQL.xml

<select id="select_list" parameterType="hashMap" resultType="hashMap">  
<![CDATA[  
select  
book_id,  
title,  
category,  
price,  
insert_date  
from  
book  
where 1 = 1  
]]>  
<if test="keyword != null and keyword != ''">  
and (title like CONCAT('%',#{keyword},'%') or category like CONCAT('%',#{keyword},'%'))  
</if>  
order by insert_date desc  
</select>  

삭제된 코드는 아래와 같다.

 
order by insert_date desc  
]]>  

추가된 코드는 아래와 같다.

where 1 = 1  
]]>  
<if test="keyword != null and keyword != ''">  
and (title like CONCAT('%',#{keyword},'%') or category like CONCAT('%',#{keyword},'%'))  
</if>  
order by insert_date desc  

where 1 =1 은 관습적인 구문이다. 1 = 1은 늘 참이기 때문에 검색 조건을 무조건 and로 연결하기 위해 사용한다.


<if 문은 마이바티스에서 조건을 나타낸다. test는 조건 규칙을 나타내는 항목이다.

<if test="keyword != null and keyword != ''">  

만약 키워드가 있으면 <if> ~ </if> 안의 쿼리문이 데이터베이스 쿼리에 포함된다. 이처럼 쿼리의 내용이 파라미터가 아니라 마이바티스의 규칙에 의해서 변경되는 것을 동적쿼리(Dynamic Query)라고 부른다.


SQL 쿼리 조건에서 포함을 나타내는 구문은 like다.

  • title like '검색어%' 일 경우는 검색어로 시작한다는 뜻이다.
  • title like '%검색어' 일 경우는 검색어로 끝난다는 뜻이다.
  • title like '%검색어%'일 경우는 검색어를 포함한다는 뜻이다.

마이바티스에서는 쿼리 파라미터에 ' 표시를 붙이지 않기 때문에 title like '%#{keyword}%' 형식으로 표기하기는 어렵다. 따라서 마리아디비의 CONCAT 함수를 이용해서 문자열을 이어붙인다.
만약 keyword 파라미터의 값이 키워드라면 CONCAT('%',#{keyword},'%') 구문은 '%키워드%' 형태로 바뀐다.


SQL 쿼리 조건에서 or 는 "또는" 을 나타내는 구문이다. A or B일때 A 혹은 B 둘 중 하나만 만족하면 참(true)를 반환한다.


<if>문 안의 내용은 제목이나 분류 안에 키워드가 있을 경우를 조건으로 한다는 뜻이다.

and (title like CONCAT('%',#{keyword},'%') or category like CONCAT('%',#{keyword},'%'))  

만약 keyword 파라미터의 값이 키워드라면 위 구문은 아래와 같은 뜻이 된다.

 
and title like '%키워드%' or category like '%키워드%'  

따라서 제목에 키워드를 포험하거나, 분류에 키워드를 포함하면 참이다.


CDATA를 닫는 항목 ]]>가 orderby 항목 아래에서 위로 변경되었다. CDATA 항목 안에 <if 등의 마이바티스 구문은 RAW 문자열로 취급하여 해석되지 않기 때문에 마이바티스 구문을 실행하기 위해 CDATA 섹션을 닫아준 것이다.

12.3. 책 검색 서비스 레이어

검색어를 전달하는 기능만 추가되므로 책 검색 서비스 레이어는 수정하지 않는다.