maverick11471 2024. 7. 15. 00:06

[요약]

 - 쿼리문을  JAVA 클래스에 구성하려면 너무 복잡하다.

 - 그걸 해결하기 위해 MyBatis로 .xml로 쿼리문을 별도 구성한다.

 

1. 정의

Sql Mapper Framework 중 하나의 종류. SQL 쿼리문을 Mapper라는 파일로 분리해서 관리하는 프레임워크.
iBatis라는 프레임워크가 독점적으로 사용되고 있었는데 
2010년 구글이 iBatis를 인수하면서 이름이 MyBatis로 변경됐다.
요즘 Sql Mapper Framework보다는 ORM 프레임워크(JPA, Hibernates 등)이 성행하고 있다.

 

2. 구조

DAO에 존재하던 쿼리문들을 Mapper라는 별도의 파일로 관리. 
스프링프레임워크에서는 xml 파일방식만 지원. 스프링부트에서는 xml파일 방식과 어노테이션 방식도 지원.
MyBatis만의 설정파일을 만들어서 조회 쿼리 결과의 표출방식 지정, 결과를 담아줄 객체의 별칭을 달아주는 설정, 
쿼리문이 저장되어 있는 Mapper 파일의 위치를 지정할 수 있는 등의 설정을 제공한다.
DAO로부터 분리된 Mapper 파일은 namespace라는 별칭을 지정하여 호출하게 되는데 
관례적으로 DAO에서 분리됐기 때문에 DAO의 이름과 동일하게 설정하는 것이 대부분.

 

3. 실행

 - pom.xml 수정 : mybatis 의존성 주입 (MVN REPOSITORY 검색)

        <!--mybatis 관련 의존성 주입-->
        <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.16</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>3.0.3</version>
        </dependency>

 

 - src-main-resources-mappings 폴더 생성 (xml 모아두는 폴더)

  * 파일생성: freboard-mapper.xml

// 기존 쿼리문의 ? 부분만 #{} 바꿔주면 된다.
// (Tip) Google - Mybatis alias 검색해서 typealias 확인 
// List 형태에서는 parameterType을 board로 줘도 된다.
// 엘리먼트가 select, insert, update 등 전부 다르니 주의

<?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">
<!--쿼리문이 Dao 클래스에서 분리되어 온 것이기 때문에 namespace는 관례적으로 Dao 클래스명과 일치시킨다.-->
<mapper namespace="FreeBoardDao">
    <insert id="post" parameterType="board">
        INSERT INTO FREEBOARD(
            TITLE,
            CONTENT,
            WRITER_ID
        ) VALUES(
            #{title},
            #{content},
            #{WRITER_ID}
        )
    </insert>

    <update id="modify" parameterType="board">
        UPDATE FREEBOARD
            SET
                TITLE = #{title},
                CONTENT = #{content},
                MODDATE = #{moddate}
            WHERE ID = #{id}
    </update>

    <select id="getBoardList" resultType="board">
        SELECT F.ID
             , F.TITLE
             , F.CONTENT
             , F.WRITER_ID
             , M.NICKNAME
             , F.REGDATE
             , F.MODDATE
             , F.CNT
            FROM FREEBOARD F
            JOIN MEMBER M
              ON F.WRITER_ID = M.ID
    </select>

    <delete id="delete" parameterType="int">
        DELETE FROM FREEBOARD
            WHERE ID = #{id}
    </delete>

    <select id="getBoard" parameterType="int" resultType="board">
        SELECT F.ID
             , F.TITLE
             , F.CONTENT
             , F.WRITER_ID
             , M.NICKNAME
             , F.REGDATE
             , F.MODDATE
             , F.CNT
            FROM FREEBOARD F
            JOIN MEMBER M
              ON F.WRITER_ID = M.ID
            WHERE F.ID = #{id}
    </select>
</mapper>

 

 - resources - sql-map-cofig.xml 파일 생성 (MySQL 설정파일)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<!-- mybatis에서 사용하는 설정파일-->
<configuration>
    <!--객체들의 별칭 지정-->
    <!--원래 Mapper에 parameterType이나 resultType에 패키지까지 포함된
        전체 클래스 명을 작성해야되는데 별칭으로 지정하면
        별칭만 사용해서 parameterType이나 resultType을 지정할 수 있다.-->
    <typeAliases>
        <typeAlias type="com.bit.springboard.dto.BoardDto"
                   alias="board"/>
        <typeAlias type="com.bit.springboard.dto.MemberDto"
                   alias="member"/>
    </typeAliases>

    <!--사용할 Sql Mapper 등록-->
    <mappers>
        <mapper resource="mappings/freeboard-mapper.xml"/>
        <mapper resource="mappings/member-mapper.xml"/>
        <mapper resource="mappings/notice-mapper.xml"/>
    </mappers>
</configuration>

 

 - root-context.xml 수정

  * SessionFactory: DB Connection Pool 관리

  * SessionTemplay: DB Conenction Poll 에서 DB Connection을 하나씩 꺼내서 사용

<!-- mybatis에서 DB Connection Pool로 관리하는 SessiontFactory 객체 bean 등록-->
    <bean id="sessionFactory"
          class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
                                                      // sql-map-config.xml 연결
        <property name="configLocation" value="classpath:sql-map-config.xml"/>
    </bean>

    <!-- mybatis의 DB Connection Pool인 SessionFactory에서 DB Connection을 하나 씩
         꺼내서 사용할 SessionTemplate 객체 bean 등록-->
    <bean class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg ref="sessionFactory"/>
    </bean>

 

 - FreeboardDao 클래스 수정

package com.bit.springboard.dao;

// SqlSessionTemplate 추가
// 쿼리문 전부 삭제
// 메서드 수정 아래 예시(쿼리문의 호출은 Mapper.xml 파일의 namespace값.쿼리문의 id)
// mybatis.insert("FreeBoardDao.post", boardDto);
// 다중 List: SelectList 메소드 사용
// 단일 객체: SelectOne 메소드 사용


@Repository
public class FreeBoardDao {
    private SqlSessionTemplate mybatis;

    @Autowired
    public FreeBoardDao(SqlSessionTemplate sqlSessionTemplate) {
        this.mybatis = sqlSessionTemplate;
    }

    public void post(BoardDto boardDto) {
        System.out.println("FreeBoardDao의 post 메소드 실행");

        mybatis.insert(/*쿼리문의 호출은 Mapper.xml 파일의 namespace값.쿼리문의 id*/"FreeBoardDao.post", boardDto);

        System.out.println("FreeBoardDao의 post 메소드 실행 종료");
    }

    public void modify(BoardDto boardDto) {
        System.out.println("FreeBoardDao의 modify 메소드 실행");

        mybatis.update("FreeBoardDao.modify", boardDto);

        System.out.println("FreeBoardDao의 modify 메소드 실행 종료");
    }

    public List<BoardDto> getBoardList() {
        System.out.println("FreeBoardDao의 getBoardList 메소드 실행");

        List<BoardDto> boardDtoList = new ArrayList<>();

        // SqlSessionTemplate의 selectList메소드 사용
        boardDtoList = mybatis.selectList("FreeBoardDao.getBoardList");

        System.out.println("FreeBoardDao의 getBoardList 메소드 실행 종료");
        return boardDtoList;
    }

    public void delete(int id) {
        System.out.println("FreeBoardDao의 delete 메소드 실행");

        mybatis.delete("FreeBoardDao.delete", id);

        System.out.println("FreeBoardDao의 delete 메소드 실행 종료");
    }
    
    public BoardDto getBoard(int id) {
        System.out.println("FreeBoardDao의 getBoard 메소드 실행");

        BoardDto boardDto = new BoardDto();

        // SqlSessionTemplate의 selectOne메소드 사용
        boardDto = mybatis.selectOne("FreeBoardDao.getBoard", id);

        System.out.println("FreeBoardDao의 getBoard 메소드 실행 종료");
        return boardDto;
    }
}

 

[sqlSessionTemplate 설명]

 

[요약]

MyBatis 라는 sql mapper framework 를 구성해서 .xml 파일에 쿼리문을 별도로 구성한다.

이를 사용하기 위해선 Mybatis 프레임워크와 스프링 프레임워크를 연결해줘야 한다.

이의 역할이 sqlSessionTemplate다. 이것은 클래스다.

이를 통해 스프링 애플리케이션 내에 MyBatis 애플리케이션을 사용할 수 있다.

 


 


SqlSessionTemplate은 MyBatis 프레임워크에서 제공하는 핵심 클래스 중 하나입니다. 

이 클래스는 MyBatis 애플리케이션에서 데이터베이스와 상호작용하는 역할을 합니다.

주요 특징은 다음과 같습니다:

SqlSessionTemplate은 스프링 프레임워크와 MyBatis를 연결해주는 역할을 합니다. 

이를 통해 MyBatis 애플리케이션을 스프링 애플리케이션 내에서 사용할 수 있습니다.

스레드 안전성을 보장하며, 트랜잭션 관리와 예외 처리 등의 기능을 제공합니다.

SqlSessionTemplate은 SqlSession을 래핑하여 제공하므로, 개발자가 직접 SqlSession을 관리할 필요가 없습니다.

따라서 이 코드에서 mybatis 변수는 MyBatis와 데이터베이스 간의 상호작용을 담당하는 핵심 객체로 사용될 것입니다. 이 객체를 통해 SQL 쿼리를 실행하고, 데이터를 조회/삽입/수정/삭제할 수 있습니다.