MyBatis

웅평·2024년 6월 26일
0

MyBatis란?

  • Mybatis는 자바 오브젝트와 SQL사이의 자동 매핑 기능을 지원하는 ORM(Object relational Mapping)프레임워크
  • SQL, 동적 쿼리, 저장 프로시저 그리고 고급 매핑을 지원하는 SQL Mapper
  • MyBatis는 JDBC를 통해 RDBMS에 액세스하는 작업을 캡슐화하고 기존 JDBC의 중복작업을 간소화해
  • XML 파일의 형태인 Mapper를 통해 프로그램 코드로부터 SQL 쿼리가 분리되는 환경을 제공하고 Java 객체와 매핑하는 작업을 도와줌

MyBatis의 사용 목적

MyBatis는 데이터베이스 쿼리 <-> 프로그래밍 언어 코드를 분리하여 유지보수성과 생산성을 높이는 것

MyBatis 특징

  1. 기존 JDBC보다 사용하기 편리
    ✔️ JDBC의 모든 기능을 Mybatis가 대부분 제공한다.
    ✔️ 수동적인 파라미터 설정과 쿼리 결과에 대한 맵핑 구문을 제거할 수 있다.
    ✔️ 기존 JDBC를 이용하여 프로그래밍을 하는 방식은 프로그램 소스안에 SQL문을 작성하는 방식으로 생산성이 좋지 않다.
    ✔️ 또, JDBC는 세부적인 작업이 가능하게 작업별로 각각의 메소드를 호출하게된다. 이러한 사항들은 다수의 메소드를 호출하고 관련된 객체를 해제해야하는 단점이 있다.

  2. SQL문과 프로그래밍 코드의 분리로 이식성이 좋다.
    ✔️ SQL에 변경이 있을 때마다 자바 코드를 수정하거나 컴파일하지 않아도 된다.
    ✔️ SQL을 별도의 파일로 분리해서 관리하게 해준다.

  3. 간단함
    ✔️ 객체 프로퍼티로 파라미터와 결과를 객체(DTO, Map 등)로 자동 매핑을 지원합니다.
    ✔️Spring 연동 모듈을 제공해주기 때문에 Spring 설정이 간단합니다.

  4. 다양한 프로그래밍 언어로 구현가능
    ✔️ Java, C#, .NET, Ruby

Mybatis 아키텍처

DB vender에서 제공하는 JDBC Driver가 있다.
JDBC만을 사용하는 어플리캐이션은 Application Modules에서 JDBC Interfaces를 바로 호출하지만 JDBC Api를 감싸서 개발자가 조금더 편리하게 접근할 수 있도록 도와주는 것이 Mybatis이다.

서비스에서 DAO를 호출하고 DAO에서 Mybatis를 사용하게된다.

Mybatis를 사용하는 데이터 액세스 계층


Mybatis는 Data Access Layer에서 사용하는 프레임워크이다.
Controller에서 Service를 호출하고 Service가 DAO계층에 있는 메소드를 호출하면 DAO에서 Mybatis를 호출한다.

MyBatis의 주요 컴포넌트


SqlSession Factory Builder, SqlSession Factory, SqlSession이 있다.

MyBatis Config File을 XML파일로 작성해두고 보라색 부분들만 개발자가 작성하면된다.

Application에서 SqlSession Factory Builder를 호출하고
SqlSession Factory Builder가 Config File을 읽고 Factory를 생성해준다. 개발자가 DB에 insert하거나 Read하는 메서드를 호출하면 SqlSession Factory가 SqlSession를 생성하고 개발자가 작성한 Application코드에 반환해준다.

SqlSession은 개발자가 작성한 SQL문을 호출해주는 기능을 해준다고 생각하면된다.

Mybatis 주요 컴포넌트의 역할

이름설명
MyBatis 설정파일 (mybatis-config.xml)DB의 접속 정보 또는 Mapping 파일의 경로, alias 등을 설정하는 XML 파일
SqlSessionFactoryBuilderMyBatis 설정파일을 읽고 SqlSessionFactory를 생성
SqlSessionFactorySqlSession을 생성
SqlSession가장 핵심적인 역할을 SQL의 실행이나 트랜잭션 관리를 수행Thread-Safe 하지 않으므로 thread 마다 필요에 따라 생성
Mapping File (mapper.xml)SQL과 객체 매핑 설정을 하는 XML 파일

Mybatis3의 Database Access 프로세스

어플리케이션 실행 시 시작되는 프로세스는 다음과 같다.

  1. 어플리케이션이 SqlSessionFactoryBuilder에게 SqlSessionFactory를 빌드하도록 요청
  2. SqlSessionFactoryBuilder는 SqlSessionFactory를 생성하기 위해 MyBatis 설정 파일을 읽음
  3. SqlSessionFactoryBuilder는 MyBatis 설정 파일의 정의에 따라 SqlSessionFactory를 생성

클라이언트의 요청에 따라 수행도는 프로세스는 다음과 같다.

  1. 클라이언트의 어플리케이션에 대한 요청
  2. 어플리케이션은 SqlSessionFactoryBuilder를 사용하여 빌드된 SqlSessionFactory에서 SqlSession을 가져옴
  3. SqlSessionFactory는 SqlSession을 생성하고 이를 어플리케이션에 반환
  4. 어플리케이션이 SqlSession에서 Mapper Interface 구현 개체를 가져옴
  5. 어플리케이션이 Mapper Interface의 메소드를 호출
  6. Mapper Interface의 구현 개체가 SqlSession 메소드를 호출하고 SQL 실행 요청
  7. SqlSession은 Mapping File에서 실행할 SQL을 찾아서 실행

Mybatis-Spring의 주요 컴포넌트

이름설명
MyBatis 설정파일(SqlMapConfig.xml)VO 객체의 정보를 설정한다.
SqlSessionFactoryMyBatis 설정파일을 바탕으로 SqlSessionFactory를 생성한다, Spring Bean으로 등록해야 한다.
SqlSessionTemplate핵심적인 역할을 하는 클래스로서 SQL 실행이나 트랜잭션 관리를 실행한다. SqlSession 인터페이스를 구현하며, Thread-safe 하다. Spring Bean으로 등록해야 한다.
Mapping 파일 (user.xml)SQL문과 OR Mapping을 설정한다.
Spring Bean 설정 파일 (mybatisBeans.xml)SqlSessionFactoryBean을 Bean 등록할 때 DataSource 정보와 MyBatis Config 파일정보, Mapping 파일의 정보를 함께 설정한다. SqlSessionTemplate을 Bean으로 등록한다.

MyBatis-Spring의 Database Access 프로세스

응용 프로그램 시작시 수행되는 프로세스

  1. SqlSessionFactoryBean은 SqlSessionFactoryBuilder를 통해 SqlSessionFactory를 빌드하도록 요청한다.
  2. 응용 프로그램은 SessionFactoryBuilder는 SqlSessionFactory 생성을 위해 MyBatis Config 파일을 읽는다.
  3. SqlSessionFactoryBuilder는 MyBatis Config 파일의 정의에 따라 SqlSessionFactory를 생성한다. 생성된 SqlSessionFactory는 Spring DI 컨테이너에 의해 저장된다.
  4. MapperFactoryBean은 SqlSession(SqlSessionTemplate) 및 Mapper 객체(Mapper 인터페이스의 프록시 객체)를 생성한다.
    생성되는 Mapper 객체는 스프링 DI 컨테이너에 의해 저장되며, Service 클래스 등에 DI가 적용된다. Mapper 객체는 안전한 SqlSession(SqlSessionTemplate)을 사용하여 쓰레드에 대해 안전한 구현을 제공한다.

클라이언트의 각 요청에 대해 수행되는 프로세스

  1. 클라이언트가 응용 프로그램에 대한 프로세스를 요청
  2. 애플리케이션은 DI 컨테이너에서 주입한 Mapper 인터페이스를 호출한다.
  3. 매퍼 객체는 호출된 메소드에 해당하는 SqlSession (SqlSessionTemplate ) 메서드를 호출한다.
  4. SqlSession(SqlSessionTemplate)은 프록시 사용 및 쓰레드에 대해 안전한 SqlSession 메서드를 호출한다.
  5. 프록시 사용 및 스레드 안전 SqlSession은 트랜잭션에 할당된 MyBatis3 표준 SqlSession을 사용한다. 트랜잭션에 할당된 SqlSession이 존재하지 않는 경우 SqlSessionFactory 메서드를 호출하여 표준 MyBatis3의 SqlSession을 가져온다.
  6. SqlSessionFactory는 MyBatis3 표준 SqlSession을 반환합니다. 반환된 MyBatis3 표준 SqlSession이 트랜잭션에 할당되기 때문에 동일한 트랜잭션 내에 있는 경우 새 SqlSession을 생성하지 않고 동일한 SqlSession을 사용한다. on 메서드를 호출하고 SQL 실행을 요청한다.
  7. MyBatis3 표준 SqlSession은 매핑 파일에서 실행할 SQL을 가져와 실행한다.

STS SpringBoot-mybatis-maven Oracle 신규 프로젝트 설정 및 DB 연동 Mapper.xml 방식 예제

STS4 버전을 사용

프로젝트 생성

[File] - [New] - [Spring Starter Project] 클릭

신규 프로젝트를 생성할 때 확인해야 할 부분입니다.

Name : Project 이름입니다. 적당하게 지어주시면 됩니다.
Type, Java Version, Packaging, Language : 라이브러리 관리를 Maven 을 이용할 것이므로 Maven 선택
( 비교적 최근 대세인 Gradle 도 선택 가능 )
Java Version 및 나머지를 본인 환경에 맞게 설정해 줍니다.
Group : 패키지 그룹명입니다.
Artifact : xxxApplication.java 가 생성되는 부분입니다. Eclipse로 치면 Main 클래스 이름이라고 생각하시면 됩니다.
Package : Application.java 파일이 위치할 패키지 명입니다.

SpringBoot 에서 기본적으로 제공하는 Dependency 부분입니다.

SpringBoot Version 확인하신 후 필요한 것들 체크하시면 됩니다.

MyBatis : MyBatis 를 사용 라이브러리
Web : 기본적인 MVC 패턴을 사용하는 라이브러리
Lombok : 편리한 DTO 구성

마이바티스 설정 파일 오류
window
preferences
Maven
Download Artifact Javadoc

보통 처음 프로젝트를 생성하면 가장 먼저 확인 해야 할 부분은
pom.xml, src/main/resources - application.properties 입니다.

application.properties

#db connection(Oracle)
spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver
spring.datasource.url=jdbc:oracle:thin:@localhost:1521:XE
spring.datasource.data-username=(userId)
spring.datasource.data-password=(userPassword)
#http port
server.port=8088
server.session.timeout=36000
#jsp
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp

port

  • 기본적으로 톰캣이 내장되어 있으며, 기본포트 8080 대신 다른 포트를 사용하는 설정입니다.
    db connection(Oracle)
  • JDBC 연동을 위한 설정입니다.
    jsp
  • jsp 사용을 위한 설정

패키지 생성

db.properties 생성

driver=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@localhost:1521:XE
username=(userId)
password=(userPassword)

DBManager.java 생성

package com.example.demo.db;

import java.io.InputStream;
import java.util.List;

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

public class DBManager {
	
	//마이바티즈 설정파일의 sql을 요청하기 위한 담당자
	private static SqlSessionFactory factory;	
	static {
		try {
			String resource = "com/example/demo/db/sqlMapConfig.xml";
			InputStream inputStream = Resources.getResourceAsStream(resource);
			factory =
			  new SqlSessionFactoryBuilder().build(inputStream);
		}catch (Exception e) {
			System.out.println("예외발생:"+e.getMessage());
		}
	}	
}

sqlMapConfig.xml 생성

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

  <properties resource="com/example/demo/db/db.properties"/>
  <typeAliases>
  	<typeAlias type="com.example.demo.vo.DeptVO" alias="deptVO"/>
  </typeAliases>
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
      </dataSource>
    </environment>
  </environments>
  <mappers>
      <mapper resource="com/example/demo/db/DeptMapper.xml"/>    
  </mappers>
</configuration>

Mapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dept">
   
  <update id="update" parameterType="deptVO">
  	update dept set dname=#{dname},dloc=#{dloc} where dno=#{dno}
  </update>

  <select id="findByDno" resultType="deptVO">
  	select * from dept where dno=#{dno}
  </select>
	
  <select id="findAll" resultType="deptVO">
    select * from dept
  </select>
  
  <insert id="insert" parameterType="deptVO">
  	insert into dept values(#{dno},#{dname},#{dloc})
  </insert>  
</mapper>

출처
https://youtu.be/9b5P4YiyqOY
https://byul91oh.tistory.com/232
https://velog.io/@cyseok123/MyBatis
https://velog.io/@changyeonyoo/Mybatis%EB%9E%80-%EC%9E%A5%EC%A0%90-%ED%8A%B9%EC%A7%95-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8

0개의 댓글