본문 바로가기

Spring

SPRING(08.20) - 검색창(sql 검색), 검색 기능 구현

MyBatis 프레임워크를 사용하여 동적 SQL 쿼리를 생성하였다. MyBatis는 Java에서 SQL을 매핑하고 실행하는 데 사용되는 프레임워크

MyBatis를 이용하면 동적 SQL을 JSTL을 사용하여 간단하게 처리할 수 있다.

<script>, <if>, <choose>, <when>, <otherwise>

 


 

@Select("""
	<script>
		SELECT COUNT(*) AS cnt
		FROM article
		WHERE 1
		<if test="boardId != 0">
			AND boardId = #{boardId}
		</if>
		<if test="searchKeyword != ''">
			<choose>
				<when test="searchKeywordTypeCode == 'title'">
					AND title LIKE CONCAT('%', #{searchKeyword}, '%')
				</when>
				<when test="searchKeywordTypeCode == 'body'">
					AND `body` LIKE CONCAT('%', #{searchKeyword},'%')
				</when>
				<otherwise>
					AND title LIKE CONCAT('%', #{searchKeyword}, '%')
					OR `body` LIKE CONCAT('%', #{searchKeyword}, '%')
				</otherwise>
			</choose>
		</if>
		ORDER BY id DESC;
	</script>		
""")

 

위의 코드에서 WHERE 1을 넣어준 이유는 뭘까? WHERE 1은 항상 참이기에 AND 조건을 추가하거나 빼는 것이 간편해지기 위해 넣어준 것이다. 없을 경우 WHERE AND boardId 가 되기에 형식이 맞지 않게 된다.

 

<if test="boardId != 0"> 는 boardId가 0이 아닐 경우 href로 들어온 boardId값을 넣어값을 select 하는 것

 

<if test="searchKeyword != ''">는 list jsp에 만들어둔 검색창에 title이나 body에 포함하거나 맞는 값을 구하기 위해 작성하면 들어오는 값이다. 따라서 검색창에 검색하게 되면

 

<choose>는 여러 조건 중 하나를 선택하는데 사용되는데 (Java에서 switch와 유사한 기능) searchKeywordTypeCode가 title이면 title에서 searchKeyword를, body면 body에서 searchKeyword를 검색하는 기능이다.

 

<otherwise>는 위의 조건이 모두 만족하지 않을 경우, title이나 body에서 searchKeyword를 검색하는 기능이다.

 


 

<div class="mb-4 flex">
			<div>${articlesCount }개</div>
			<div class="flex-grow"></div>
			<!-- 			<form action="../article/list"> -->
			<form action="">
				<input type="hidden" name="boardId" value="${param.boardId }" />
				<div class="flex">
					<select class="select select-sm select-bordered
						max-w-xs" name="searchKeywordTypeCode"
						data-value="${param.searchKeywordTypeCode } ">
						<option value="title">title</option>
						<option value="body">body</option>
						<option value="title,body">title+body</option>
						<option value="nickname">nicnkname</option>
					</select> <label class="ml-3 input input-bordered input-sm flex items-center gap-2"> <input type="text"
						placeholder="Search" name="searchKeyword" value="${param.searchKeyword }" />
						<button type="submit">
							<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="h-4 w-4 opacity-70">
    <path fill-rule="evenodd"
									d="M9.965 11.026a5 5 0 1 1 1.06-1.06l2.755 2.754a.75.75 0 1 1-1.06 1.06l-2.755-2.754ZM10.5 7a3.5 3.5 0 1 1-7 0 3.5 3.5 0 0 1 7 0Z"
									clip-rule="evenodd" />
  </svg>
						</button>
					</label>
				</div>
			</form>
		</div>

 

 

<input type="hidden" name="boardId" value="${param.boardId }" />로 boardId 값을 숨겨 form과 함께 전송한다.

 

<select> 는 검색 조건을 선택한다. name으로 searchKeywordTypeCode를 지정해주어야 선택된 검색 조건을 서버로 전송할 경우 사용될 수 있고, data-value="${param.searchKeywordTypeCode } " 데이터의 기본 값은 controller의 파라미터에 해당하는 searchKeywordTypeCode로 초기화한다. 이렇게 되면 선택하고 검색 버튼을 눌러도 그 선택한 상태를 유지할 수 있게 된다.

 

<option> 태그들은 사용자가 선택할 수 있는 것

 

<input type="text" placeholder="Search" name="searchKeyword" value="${param.searchKeyword }" /> value값을 ${param.searchKeyword } 해줌으로써 검색어 창에 검색한 값을 유지할 수 있게 해준다.

 


 

<select class="select select-sm select-bordered max-w-xs" name="searchKeywordTypeCode" data-value="${param.searchKeywordTypeCode } ">

 

data-value 속성은 기본적으로 <select> 에서 사용되지 않는다.

값을 설정하려면 JavaScript를 사용하여 data-value 속성에서 값을 읽고 <select> 요소의 선택된 값으로 설정해야 한다.

 

JavaScript

$('select[data-value]').each(function(index, el) {
	const $el = $(el);

	defaultValue = $el.attr('data-value').trim();

	if (defaultValue.length > 0) {
		$el.val(defaultValue);
	}
});

 

$('select[data-value]') 에서 위에서 data-value 속성이 설정된 <select> 요소를 선택한다. .each(function(index, el) 로 선택된 요소들 각각에 대하여 반복 작업을 수행하고, index는 현재 요소의 순서, el은 현재요소

const $el = $(el); 는 변수 선언이라고 보면 된다. 현재요소 el을 $el에 저장

 

defaultValue = $el.attr('data-value').trim();

 

data-value 속성 값을 가져와서 trim으로 공백 제거한 후 defaultValue 변수에 저장한다.
(attr은 jQuery에서 HTML 요소의 속성 값을 읽거나 설정하는데 사용하는 메서드)

 

if (defaultValue.length > 0) {
$el.val(defaultValue);
}

 

data-value 속성 값이 있는 경우 해당 요소의 선택된 값을 설정,
(val 메서드는 HTML 폼 요소의 값을 쉽게 가져오거나, 설정할 수 있게 해준다.)


따라서, 옆의 검색어를 입력 후 검색하여도 왼쪽 선택한 값이 변하지 않고 유지할 수 있도록 해주는 것이다.