DB

[MyBatis] MyBatis 개념 및 구조

yn98 2024. 11. 4. 15:16

 

MyBatis란 ?

MyBatis는 예전에 iBatis로 불렸던 프레임워크로, 객체와 데이터베이스의 매핑을 관리하며 SQL 쿼리를 XML로 분리해 관리하는 특징을 갖는다. 이 방식으로 Java 코드의 SQL 쿼리 의존도를 낮추면서도 필요한 쿼리를 직접 작성할 수 있어 효율적이다.

MyBatis 장점

 

코드 간결화: Java 코드에서 SQL을 분리함으로써 코드 길이가 줄어들고, 가독성이 높아진다.

SQL 분리 관리: SQL 구문을 XML 파일로 따로 관리할 수 있어 결합도가 낮아지고 응집도는 높아진다. 따라서 유지보수도 용이해진다.

비용 절감: SQL 구문에 변경이 생길 때 XML 파일만 수정하면 되므로, Java 코드를 재컴파일할 필요가 없어 비용 절감 효과가 있다.

ORM (Object - Relational Mapping) 플러그인

ORM은 객체 지향 프로그래밍 방식과 관계형 데이터베이스 시스템(RDBMS) 간의 데이터 변환(매핑)을 도와주는 도구이다.

DTO(Data Transfer Object)나 VO(Value Object) 같은 자바 객체를 테이블과 매핑하고, SQL 구문을 XML 파일에 작성하여 관리하게 한다.

ORM 설정을 추가해 DB 로직을 자동화할 수 있으며, 프로젝트의 pom.xml 파일에 이 설정을 포함시킨다.

 

 


MyBatis 설정 및 설명 + 예시 코드

 프로젝트에 MyBatis를 사용하려면 pom.xml 파일에 MyBatis 의존성을 추가해야 한다.

<!--마이바티스 쓸건데-->
         <dependency>
        	 <groupId>org.mybatis</groupId>
    	     <artifactId>mybatis</artifactId>
         <version>3.5.6</version>
	    </dependency>
    	  <!-- 스프링이랑 연동할거야-->
    	  <dependency>
     		    <groupId>org.mybatis</groupId>
    		  	<artifactId>mybatis-spring</artifactId>
     		    <version>2.1.0</version>
     	 </dependency>

sql-map-config.xml

MyBatis의 메인 설정 파일로, 여기서 별칭을 정의하고 SQL 구문 XML 파일들을 매핑해준다.

<?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">
<configuration>
    <!-- 자료형에 별칭(alias) 붙여주기 -->
    <typeAliases>
        <typeAlias type="com.yn.app.biz.board.BoardDTO" alias="board" />
    </typeAliases>

    <!--  SQL 구문 설정파일 알려주기 -->
    <!--  빼낸 SQL 구문이 어디로 갔는가 ? 를 알려줌 -->
    <mappers>
        <mapper resource="mappings/board-mapping.xml" />
    </mappers>
</configuration>

 

typeAlias를 통해 BoardDTO 클래스를 board라는 별칭으로 사용하여 가독성을 높였다.

예시로 이따 정리하게 될 board-mapping.xml 파일에는 Board 관련 SQL 구문이 담긴다.


applicationContext.xml

Spring과 MyBatis를 연결하는 설정 파일로, 데이터 소스 및 트랜잭션 매니저를 설정하고 MyBatis의SqlSessionFactoryBean과 SqlSessionTemplate을 정의한다.

<bean class="org.apache.commons.dbcp.BasicDataSource" id="ds" destroy-method="close">
    <property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://localhost:3306/스키마명" />
    <property name="username" value="root" />
    <property name="password" value="비밀번호" />
</bean>

<bean id="sqlSession" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="ds" />
    <property name="configLocation" value="classpath:sql-map-config.xml" />
</bean>

<bean id="mybatis" class="org.mybatis.spring.SqlSessionTemplate">
    <constructor-arg ref="sqlSession" />
</bean>

 

 

SqlSessionFactoryBean은 MyBatis가 데이터베이스 정보와 설정을 불러오는 데 필요한 객체다.

SqlSessionTemplate은 MyBatis의 주요 기능을 호출하기 위한 템플릿 역할을 하며, DAO에서 SQL 구문을 호출할 때 사용된다.


 board-mapping.xml ( Mapper 파일 구조 예시 )

<?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">
<!-- 만약 namespace가 없다면 ..? -->
<!-- 태그들이 다른 xml이란 것을 구분할 수 없다. -->
<!-- 예를들어 insert는 .. BoardDAO의 insert이다. 이런식으로 알 수 있다. -->
<!-- 현업에서는 다른 namespace를 쓰는 경우도 많다. -->
<mapper namespace="BoardDAO">
    <!-- 아래가 insert 구문이라는걸, insert 태그를 통해 알 수 있다. -->
    <insert id="insert">
        INSERT INTO BOARD (CONTENT,WRITER)
        VALUES(#{content},#{writer})
    </insert>
    <select id="selectOne" resultType="board">
        SELECT BID,CONTENT,WRITER FROM BOARD
        WHERE BID=#{bid}
    </select>
    <select id="selectAll" resultType="board">
        SELECT BID,CONTENT,WRITER FROM BOARD
    </select>
    <select id="selectAll_CONTENT" resultType="board">
        SELECT BID,CONTENT,WRITER FROM BOARD
        <!-- ORM mybatis 파라미터를 받는 문법 #{} 객체이름..멤버변수 쓰면 됨 -->
        WHERE CONTENT LIKE CONCAT('%',#{keyword},'%')
    </select>
    <!-- resultType는 원래 .. com.yn.app.bia.board.BoardDTO 를 써야하지만 아까 as 설정해서 board로 바꾼것 -->
    <!-- 별칭 설정은 필수는 아니지만, 가독성 ↑ -->
    <select id="selectAll_WRITER" resultType="board">
        SELECT BID,CONTENT,WRITER FROM BOARD
        WHERE WRITER=#{keyword}
    </select>
</mapper>

 


BoardDAO3.java

MyBatis를 사용하여 코드와 쿼리를 분리 관리할 수 있도록 수정했다.

이로 인해 결합도는 낮추고 유지보수성을 높여주며, 자바 코드도 깔끔해진다. ORM을 통해 자바 객체와 테이블을 매핑하여 객체 지향 프로그래밍과 관계형 데이터베이스 간의 데이터 관리가 용이해진다.

package com.yn.app.biz.board;

import java.util.List;

import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;


@Repository
public class BoardDAO3 {

    @Autowired
    private SqlSessionTemplate mybatis;

    public List<BoardDTO> selectAll(BoardDTO boardDTO) {
        //SELECTALL_CONTENT 호출
        if(boardDTO.getCondition()!= null && boardDTO.getCondition().equals("CONTENT")) {
            //return 결과반환;
            //return mybatis.selectList("어떤 SQL을 부를지", boardDTO);
            return mybatis.selectList("BoardDAO.selectALL_CONTENT", boardDTO);
        }
        else if(boardDTO.getCondition()!= null && boardDTO.getCondition().equals("WRITER")) {
            //SELECTALL_WRITER 호출
            //return 결과반환;
            return mybatis.selectList("BoardDAO.selectALL_WRITER", boardDTO);
        }
        //SELECTALL 호출

        return mybatis.selectList("BoardDAO.selectAll", boardDTO); // namespace.id
    }

    //return datas;
    public BoardDTO selectOne(BoardDTO boardDTO) {
        return mybatis.selectOne("BoardDAO.selectOne", boardDTO);
    }
    public boolean insert(BoardDTO boardDTO) {
        int result = mybatis.insert("BoardDAO.insert", boardDTO);
        if(result <= 0) {
            return false;
        }
        return true;
    }
    public boolean update(BoardDTO boardDTO) {
        return false;
    }
    public boolean delete(BoardDTO boardDTO) {
        return false;
    }


}