구리

TIL_210629_Spring Mapper XML 파일 설정 본문

SPRING FRAMEWORK

TIL_210629_Spring Mapper XML 파일 설정

guriguriguri 2021. 6. 29. 15:11

목차

SQL Mapper XML 기본 설정
1. Mybatis 구조
2. Mapper XML 파일 구조
3. <select> 엘리먼트

SQL Mapper XML 추가 설정
1. resultMap 속성 사용
2. CDATA Section 사용

Mybatis JAVA API
1. SqlSessionFactoryBuilder 클래스
2. SqlSessionFactory  클래스
<SqlSession 객체 생성 방법>
3. 유틸리티 클래스 작성
4. SqlSession 객체

 

 

 

SQL Mapper XML 기본 설정

1. Mybatis 구조

SqlMapConfig.xml 파일은 Mybatis 메인 환경 설정 파일로 Mybatis는 이 파일을 읽어 어떤 DBMS와 커넥션을 맺을지, 어떤 SQL Mapper XML 파일들이 등록되었는지 알 수 있습니다.

Mybatis는 SqlMap.xml 파일에 등록된 각 명령어들을 Map 구조로 저정하여 관리합니다.

 

2. Mapper XML 파일 구조

Mybatis 프레임워크에서 가장 중요한 파일로 SQL 명령어들이 저장되는 SQL Mapper XML 파일입니다.

<mapper>를 루트 엘리먼트로 가지며 기본 구조는 다음과 같습니다.

가장 먼저 DTD 선언 후 <mapper> 루트 엘리먼트가 선언되는데 namespace 속성으로 유일한 SQL 아이디를 생성할 수 있습니다.

Mapper XML <mapper namespace="BoardDAO">
          <delete id="deleteBoard">
           delete from board where seq=#{seq}
           </delete>
</mapper>
DAO 클래스  public void deleteBoard(BoardVO vo){
            mybatis.delete("BoardDAO.deleteBoard", vo);
}

 

3. <select> 엘리먼트

데이터 조회하는 SELECT 구문 작성시 사용합니다

예시

<mapper namespace="BoardDAO">
	<select id="getBoard" resultType="board">
		select * from board where seq=#{seq}
	</select>
	
	<select id="getBoardList" resultType="board">
		select * from board where title like '%'||#{searchKeyword}||'%' order by seq desc
	</select>
</mapper>

id 속성

반드시 전체 Mapper 파일들 내에서 유일한 아이디로 등록해야 하고 <mapper> 엘리먼트에 설정된 네임스페이스는 엘리먼트 안에 선언된 여러 아이디를 하나의 네임스페이스로 묶을 수 있습니다.

예시로 아래의 "getTotalCount" id는 네임스페이스가 다르므로 다른 아이디로 처리될 수 있습니다.

board-mapping.xml user-mapping.xml
<mapper namespace="BoardDAO">
<select id="getTotalCount" resultType="int">
  select count(*) from board
</select>
</mapper>
<mapper namespace="UserDAO">
<select id="getTotalCount" resultType="int">
  select count(*) from users
</select>
</mapper>

 

② parameterType 속성

SQL 실행에 필요한 데이터를 외부로부터 받아야 할 때 사용하는 속성으로 일반적으로 기본형이라 VO 형태의 클래스를 지정합니다. 이때, MyBatis 메인 설정 파일(sql-map-config.xml)에 등록된 <typeAlias>를 사용하면 설정을 더 간결히 처리할 수 있습니다.

(설정 후 사용하는 것을 권장하며 <typeAlias>로 설정한 값이 아닌 별도의 값을 전달받아서 처리할 경우 사용 )

 

③ resultType 속성

ResultSet이 리턴되는데, 검색결과를 어떤 자바 객체에 매핑할지 명시할 때 사용합니다.

parameterType 속성과 달리 절대 생략할 수 없으며 대신 resultMap 속성으로 대체 가능합니다.

 

④ <insert> 엘리먼트

DB에서 데이터를 삽입하는 INSERT 구문을 작성하는 요소로 <selectKey> 엘리먼트로 생성된 기본 키를 쉽게 가져옵니다.

<insert id="insertBoard" parameterType="board">
		<selectKey keyProperty="seq" resultType="int">
			select board_seq.nextval as seq from dual
		</selectKey>
		insert into board(seq,title, writer, content)
		values (#{seq},#{title},#{writer},#{content})
	</insert>

이 설정은 "BOARD_SEQ"라는 시퀀스로부터 유일한 킷값을 얻어내 글 등록에서 일련번호(seq)값으로 사용하는 설정입니다.

 

⑤ <update> 엘리먼트

데이터 수정시 사용되는 UPDATE 구문 작성하는 요소

<mapper namespace="BoardDAO">
	<update id="updateBoard">
		update board set title=#{title}, content=#{content} where seq=#{seq}
	</update>
</mapper>

 

⑥ <delete> 엘리먼트

데이터 삭제시 사용되는 DELETE 구문을 작성하는 요소

<mapper namespace="BoardDAO">
	<delete id="deleteBoard">
		delete from board where seq=#{seq}
	</delete>
</mapper>

 

SQL Mapper XML 추가 설정

1. resultMap 속성 사용

검색 결과를 parameterType 속성으로 매핑할 수 없을 때 사용합니다.

<mapper namespace="BoardDAO">
	<resultMap id="boardResult" type="board">
		<id property="seq" column="SEQ" />
		<result property="title" column="TITLE"/>
		<result property="writer" column="WRITER" />
		<result property="content" column="CONTENT" />
		<result property="regDate" column="REGDATE" />
		<result property="cnt" column="CNT" />
	</resultMap>
	
	<select id="getBoardList" resultMap="boardResult">
		select * from board where title like '%'||#{searchKeyword}||'%' order by seq desc
	</select>
</mapper>

위 설정은 boardResult라는 아이디로 <resultMap>을 설정했습니다.

<resultMap> 설정은 PK에 해당하는 SEQ 칼럼만 <id> 엘리먼트를 사용하고 나머지는 <result> 엘리먼트를 이용해 결과로 얻어낸 칼럼의 값과 BoardVO 객체의 변수를 매핑하고 있습니다.

 

2. CDATA Section 사용

Mybatis와는 상관없는 XML 고유의 문법으로 해당 영역에 작성된 데이터는 XML 파서가 해석하지 않도록 하고 데이터베이스에 그대로 전달합니다.

XML 파서는 XML 파일 처리시 <, > 같은 기호를 또 다른 태그의 시작으로 처리하기에 CDATA Section으로 SQL 구문을 감싸줘 에러를 방지합니다.따라서 지금 당장은 아니더라도 나중을 대비해 모든 SQL 구문을 CDATA Section으로 처리합니다.

<select id="getBoard" resultType="board">
		<![CDATA[
			select * from board where seq <= #{seq}
		]]>
	</select>

 

수정된 board-mapping.xml 코드

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="BoardDAO">
	<resultMap id="boardResult" type="board">
		<id property="seq" column="SEQ" />
		<result property="title" column="TITLE"/>
		<result property="writer" column="WRITER" />
		<result property="content" column="CONTENT" />
		<result property="regDate" column="REGDATE" />
		<result property="cnt" column="CNT" />
	</resultMap>
	
	<insert id="insertBoard" parameterType="board">
		<![CDATA[ 
			INSERT INTO BOARD(SEQ,TITLE, WRITER, CONTENT)
			VALUES ((SELECT NVL(MAX(SEQ),0)+1 FROM BOARD),
			#{title}, #{writer}, #{content})
		]]>
	</insert>
	
	<update id="updateBoard">
		<![CDATA[ 
			UPDATE BOARD SET 
				TITLE=#{title}, 
				CONTENT=#{content} 
			WHERE SEQ=#{seq}
		]]>
	</update>
	
	<delete id="deleteBoard">
		<![CDATA[ 
			DELETE BOARD 
			WHERE SEQ=#{seq}
		]]>
	</delete>
	
	<select id="getBoard" resultType="board">
		<![CDATA[ 
			SELECT * 
			FROM BOARD 
			WHERE SEQ=#{seq}
		]]>
	</select>
	
	<select id="getBoardList" resultMap="boardResult">
		<![CDATA[ 
			SELECT * 
			FROM BOARD 
			WHERE TITLE LIKE '%'||#{searchKeyword}||'%' 
			ORDER BY SEQ DESC
		]]>
	</select>
</mapper>

 

 

Mybatis JAVA API

1. SqlSessionFactoryBuilder 클래스

Mybatis 프레임워크에서 제공하는 API를 이용해 DAO 클래스를 구현

Mybatis로 DAO 클래스의 CRUD 메소드를 구현하려면 SqlSession 객체를 사용

 

2. SqlSessionFactory  클래스

SqlSession 객체에 대한 공장 역할을 수행, openSession() 메소드 이용

 

<SqlSession 객체 생성 방법>

① Resources 클래스의 getResourcesAsReader() => 입력 스트림인 Reader 객체를 얻어내 sql-map-config.xml 파일을 로딩

② SqlSessionFactoryBuilder의 build() => Mybatis 설정 파일(sql-map-config.xml)을 로딩하여 SqlSessionFactory 객체  생성

③ 생성된 SqlSessionFactory  객체로 openSession() => SqlSession 객체 생성

Reader reader = Resources.getResourceAsReader("sql-map-config.xml");
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);

SqlSession session = sessionFactory.openSession();
session.insert("BoardDAO.inserBoard", vo);

 

3. 유틸리티 클래스 작성

DAO 클래스에서 더 쉽게 SqlSession 객체를 획득할 수 있도록 공통으로 제공할 유틸리티 클래스 생성

(나중에는 Mybatis를 스프링과 연동할 때 프레임워크에서 제공하는 클래스를 사용)

package com.springbook.biz.util;

import java.io.Reader;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSession;

public class SqlSessionFactoryBean {
	private static SqlSessionFactory sessionFactory = null;
	static{
		try{
			if(sessionFactory==null){
				Reader reader = Resources.getResourceAsReader("sql-map-config.xml");
				sessionFactory = new SqlSessionFactoryBuilder().build(reader);
			}
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	public static SqlSession getSqlSessionInstance(){
		return sessionFactory.openSession();
	}
}

 

4. SqlSession 객체

Mapper XML에 등록된 SQL을 실행하기 위한 다양한 API 제공

① selectOne()

오직 하나의 데이터 검색하는 SQL 구문 실행시 사용 (조회용 메소드 구현시 사용!)

public Object selectOne(String statement)
public Object selectOne(String statement, Object parameter)

② selectList()

여러 개의 데이터가 검색되는 SQL 구문 실행시 사용

public Object selectList(String statement)
public Object selectList(String statement, Object parameter)

③ insert(), update(), delete()

각 메소드는 실행된 SQL 구문으로 인해 몇 건의 데이터가 처리되었는지를 리턴

public int insert(String statement, Object parameter)
public int update(String statement, Object parameter) throws SQLException
public int delete(String statement, Object parameter) throws SQLException

 

다음은 SqlSession 객체를 이용해 구현한 BoardDAO 클래스의 전체 소스입니다.

package com.springbook.biz.board.impl;

import java.util.List;

import org.apache.ibatis.session.SqlSession;

import com.springbook.biz.board.BoardVO;
import com.springbook.biz.util.SqlSessionFactoryBean;

public class BoardDAO {
	private SqlSession mybatis;
	
	public BoardDAO() {
		mybatis = SqlSessionFactoryBean.getSqlSessionInstance();
	}

	// 글 등록
	public void insertBoard(BoardVO vo){
		mybatis.insert("BoardDAO.insertBoard", vo);
		mybatis.commit();
	}
	
	// 글 수정
	public void updateBoard(BoardVO vo){
		mybatis.update("BoardDAO.updateBoard", vo);
		mybatis.commit();
	}
	
	// 글 삭제
	public void deleteBoard(BoardVO vo){
		mybatis.delete("BoardDAO.deleteBoard", vo);
		mybatis.commit();
	}
	
	// 글 상세 조회 
	public BoardVO getBoard(BoardVO vo){
		return (BoardVO)mybatis.selectOne("BoardDAO.getBoard", vo);
	}
	
	// 글 목록 조회
	public List<BoardVO> getBoardList(BoardVO vo){
		return mybatis.selectList("BoardDAO.getBoardList", vo);
	}
}

'SPRING FRAMEWORK' 카테고리의 다른 글

TIL_210705_JPA 환경 설정  (0) 2021.06.29
TIL_210705_JPA 개념  (0) 2021.06.29
TIL_210629_Spring Mybatis 프레임워크 시작  (0) 2021.06.29
TIL_210624_Spring 데이터 변환  (0) 2021.06.23
TIL_210624_Spring 다국어 처리  (0) 2021.06.23