Spring/Maven Project

Spring에 Mapper XML - Search 공통 처리, DAO - 카운트 기능 추가

carrotweb 2022. 10. 23. 22:19
728x90
반응형

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>을 생성합니다.

  1. <sql> 안에 <where>을 넣습니다.
  2. <sql>의 id 속성은 쿼리문을 구분하는 식별자로 중복되지 않는 이름으로 입력합니다.
  3. 게시판에서 공통적으로 많이 사용하는 검색 범위는 게시물의 제목이나 게시물의 제목과 내용을 모두 검색하는 겁니다. 그래서 검색 타입(searchType)은 제목(subject), 제목과 내용(subjectandcontent)이 됩니다. 두 번째 <when>의 test 속성을 content에서 subjectandcontent으로 변경합니다.
  4. 두 번째 <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>에 추가합니다.

  1. <select>에서 <where>를 삭제하고 <sql>를 가져오기 위해서 <include>를 추가합니다.
  2. <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>으로 카운트 쿼리문을 생성합니다.

  1. <select>의 parameterType 속성에 BoardSearch 클래스를 입력합니다.
  2. 조회된 수를 받기 위해서 <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);
	}
}

728x90
반응형