Mapper XML에서 검색 조건 Model(모델)를 사용하여 <select>에서 <where>를 추가하여 처리하였습니다.
그런데 동일한 검색 조건 Model(모델)이 다른 <select>에서도 사용된다면 어떻게 해야 할까요? 그냥 <select>에 <where>를 동일하게 추가해도 됩니다. 그런데 검색 조건이 추가되거나 수정된다면 모든 <select>에서 <where>를 수정해야 하는 번거로움이 있습니다. 그래서 Mapper XML에서는 동일하게 사용되는 쿼리문을 분리하여 재사용할 수 있게 <sql>를 지원하고 있습니다.
<select>에서 동일하게 사용될 <where>를 <sql>로 분리하여 재사용되도록 수정하겠습니다.
Maven Spring Project에 Board Mapper XML 수정하기
1. com.home.study.test1.sqlmapl.mappers.mariadb.board 패키지에 있는 BoardMapper.xml 파일을 오픈합니다.
2. 공통으로 처리될 검색 조건을 분리하기 위해 <sql>을 생성합니다.
- <sql> 안에 <where>을 넣습니다.
- <sql>의 id 속성은 쿼리문을 구분하는 식별자로 중복되지 않는 이름으로 입력합니다.
- 게시판에서 공통적으로 많이 사용하는 검색 범위는 게시물의 제목이나 게시물의 제목과 내용을 모두 검색하는 겁니다. 그래서 검색 타입(searchType)은 제목(subject), 제목과 내용(subjectandcontent)이 됩니다. 두 번째 <when>의 test 속성을 content에서 subjectandcontent으로 변경합니다.
- 두 번째 <when>가 제목과 내용(subjectandcontent)이기 때문에 제목(subject)이나 내용(content)에서 검색 조건(searchCondition) 따라 검색 키워드(searchKeyword)가 있는지 비교하기 위해 OR 조건으로 처리합니다.
<sql id="whereBoardSearch">
<where>
<if test='searchKeyword != null and searchKeyword != ""'>
<choose>
<when test='searchType != null and searchType == "subject"'>
<choose>
<when test='searchCondition != null and searchCondition == "like"'>
BRD.BRD_SUBJECT LIKE CONCAT('%',#{searchKeyword},'%')
</when>
<otherwise>
BRD.BRD_SUBJECT = #{searchKeyword}
</otherwise>
</choose>
</when>
<when test='searchType != null and searchType == "subjectandcontent"'>
<choose>
<when test='searchCondition != null and searchCondition == "like"'>
(BRD.BRD_SUBJECT LIKE CONCAT('%',#{searchKeyword},'%')
OR BRD.BRD_CONTENT LIKE CONCAT('%',#{searchKeyword},'%'))
</when>
<otherwise>
(BRD.BRD_SUBJECT = #{searchKeyword}
OR BRD.BRD_CONTENT = #{searchKeyword})
</otherwise>
</choose>
</when>
</choose>
</if>
</where>
</sql>
<where>에는 하나의 조건만 있는 게 아니라 여러 조건들이 있을 수 있습니다. 그래서 여러 조건들이 같이 처리될 수 있기 때문에 여러 개의 비교문이 동시에 처리되기 위해서는 AND 조건으로 처리되어야 합니다. 그래서 비교문 앞에 AND를 추가해 줍니다. 그러나 SELECT의 WHERE 절이 AND로 시작될 수 없기 때문에 <where>에 첫 번째 조건문으로 항상 참인 의미 없는 조건 1=1을 추가합니다. 고정으로 처리되는 비교문이 있다면 1=1을 사용할 필요는 없지만 조건에 따라 동적으로 비교문이 사용된다면 의미 없는 조건인 1=1은 필요합니다.
<sql id="whereBoardSearch">
<where>
1=1
<if test='searchKeyword != null and searchKeyword != ""'>
<choose>
<when test='searchType != null and searchType == "subject"'>
<choose>
<when test='searchCondition != null and searchCondition == "like"'>
AND BRD.BRD_SUBJECT LIKE CONCAT('%',#{searchKeyword},'%')
</when>
<otherwise>
AND BRD.BRD_SUBJECT = #{searchKeyword}
</otherwise>
</choose>
</when>
<when test='searchType != null and searchType == "subjectandcontent"'>
<choose>
<when test='searchCondition != null and searchCondition == "like"'>
AND (BRD.BRD_SUBJECT LIKE CONCAT('%',#{searchKeyword},'%')
OR BRD.BRD_CONTENT LIKE CONCAT('%',#{searchKeyword},'%'))
</when>
<otherwise>
AND (BRD.BRD_SUBJECT = #{searchKeyword}
OR BRD.BRD_CONTENT = #{searchKeyword})
</otherwise>
</choose>
</when>
</choose>
</if>
</where>
</sql>
3. 생성한 <sql>를 <select>에 추가합니다.
- <select>에서 <where>를 삭제하고 <sql>를 가져오기 위해서 <include>를 추가합니다.
- <include>의 refid 속성에 <sql>의 id을 입력하면 <sql>에 있는 쿼리문이 포함되게 됩니다.
<!--
게시판 리스트를 가져옵니다.
-->
<select id="selectBoardList" parameterType="BoardSearch" resultMap="BoardMap">
SELECT BRD.BRD_SEQ,
BRD.BRD_SUBJECT,
BRD.REG_ID,
DATE_FORMAT(BRD.REG_DTM, '%Y-%m-%d %H:%i:%s') AS REG_DTM
FROM INT_BOARD_TB BRD
<include refid="whereBoardSearch"/>
</select>
Maven Spring Project에 Board Mapper XML에 카운트 쿼리 추가하기
1. INT_BOARD_TB(게시판) Table에서 검색 조건에 맞는 데이터(게시물) 수를 조회(select) 하기 위해서 <select>으로 카운트 쿼리문을 생성합니다.
- <select>의 parameterType 속성에 BoardSearch 클래스를 입력합니다.
- 조회된 수를 받기 위해서 <select>의 resultType 속성에 int를 입력합니다.
<!--
게시판 리스트 카운트를 가져옵니다
-->
<select id="selectBoardListCount" parameterType="BoardSearch" resultType="int">
SELECT COUNT(*) AS COUNT
FROM INT_BOARD_TB BRD
<include refid="whereBoardSearch"/>
</select>
Maven Spring Project에 DAO - Board Interface 수정하기
1. Java Resource > src/main/java에서 com.home.study.test1.board.dao 패키지에 있는 IBoardDao Interface(인터페이스)를 오픈합니다. (IBoardDao.java)
2. INT_BOARD_TB(게시판) Table에서 검색 조건에 맞는 데이터(게시물) 수를 조회(select)하여 리턴하는 selectBoardListCount 메서드를 선언합니다.
package com.home.study.test1.board.dao;
import java.util.List;
import com.home.study.test1.board.model.Board;
import com.home.study.test1.board.model.BoardSearch;
public interface IBoardDao {
int selectBoardListCount(BoardSearch boardSearch);
List<Board> selectBoardList(BoardSearch boardSearch);
}
Maven Spring Project에 DAO - Board Implement 수정하기
1. Java Resource > src/main/java에서 com.home.study.test1.board.dao.impl 패키지에 있는 BoardDaoImpl 클래스를 오픈합니다. (BoardDaoImpl.java)
2. BoardDaoImpl 클래스에서 IBoardDao Interface(인터페이스)의 selectBoardListCount 메서드를 구현합니다.
org.apache.ibatis.session.SqlSession.selectOne(String statement, Object parameter)
SqlSession의 selectOne 메서드의 첫 번째 파라미터인 statement는 실행 구문의 고유 식별자로 문자열 변수(SQL_FILE_PATH)와 <select>의 id 속성 값을 결합한 값입니다. 두 번째 파라미터인 parameter는 실행 구문에 전달할 객체로 boardSearch 변수를 입력합니다.
SqlSession의 selectOne 메서드는 리턴 값으로 Object 객체를 리턴하기 때문에 숫자를 받기 위해서는 Integer 객체로 형 변환해야 합니다. 그리고 int로 리턴하기 위해서 Integer의 intValue 메서드로 변환해야 합니다.
package com.home.study.test1.board.dao.impl;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;
import com.home.study.test1.board.dao.IBoardDao;
import com.home.study.test1.board.model.Board;
import com.home.study.test1.board.model.BoardSearch;
@Repository("BoardDaoImpl")
public class BoardDaoImpl implements IBoardDao {
protected static final String SQL_FILE_PATH = "com.home.study.test1.board.mapper.mariadb.BoardMapper.";
@Autowired
@Qualifier("sqlSessionMariaDB")
private SqlSession sqlSession;
@Override
public int selectBoardListCount(BoardSearch boardSearch) {
return ((Integer)sqlSession.selectOne(SQL_FILE_PATH + "selectBoardListCount", boardSearch)).intValue();
}
@Override
public List<Board> selectBoardList(BoardSearch boardSearch) {
return sqlSession.selectList(SQL_FILE_PATH + "selectBoardList", boardSearch);
}
}
'Spring > Maven Project' 카테고리의 다른 글
Spring에 Data 전달 - GET, POST, HttpServletRequest getParameter (0) | 2022.11.06 |
---|---|
Spring에 Service - Interface, Implement 추가 (0) | 2022.10.31 |
Spring에 DAO - Search Model 추가, Mapper XML - WHERE 적용 (0) | 2022.10.15 |
Spring에 DAO - Interface, Implement 추가 (0) | 2022.10.03 |
Spring에 Model, Mapper XML 추가 (0) | 2022.10.02 |