구리

[Mybatis] Mybatis 구조 본문

SPRING FRAMEWORK

[Mybatis] Mybatis 구조

guriguriguri 2021. 7. 2. 14:15

 

프로그램 실행시 root-context.xml에 의하여 SqlSessionFactory와 SqlSessionTemplate 객체가 생성되어 메모리에 올라가게 됩니다.

팩토리를 설계하기 위해선 MyBatis Config File 이 필요합니다.

 

유저의 요청이 들어오면 SqlSessionFactory로부터 SqlSession을 생성하고  SqlSession은 DB와 연결 상태(세션)을 유지하는 역할을 합니다.

DB와 연결만 되어있을뿐, 어떤 sql을 DB에 날릴 지는 결정되어 있지 않기 때문에 SqlSession은 Mapper Interface의 구현 객체를 생성합니다. 

그리고 애플리케이션에서 Mapper Interface의 구현 객체의 메소드를 실행하면 실행 중에 동적으로 매핑파일의 sql 내용을 참고하여 DB에 쿼리를 날리게 됩니다.

 

package com.bjy.todolist.repository;

import java.util.ArrayList;
import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.bjy.todolist.dto.Todo;
import com.bjy.todolist.dto.TodoMapper;

@Repository
public class TodoRepository {	// 기존의 DAO 역할(servlet-context.xml의 <annotation-driven />에 의해 자동 등록)

	@Autowired
	SqlSession sqlsession;	// 컨테이너의 SqlSession과 동일한 타입 객체 존재할 경우 자동 주입
							// root-context.xml의 <bean id="sqlSession" ~>에 의해 등록된 상태
	
	public TodoRepository() {
	}

	//Todo 추가
	 public int insertTodo(Todo todo) {
	  int result = 0;

	  TodoMapper mapper = sqlsession.getMapper(TodoMapper.class);

	  try {
	   result = mapper.insertTodo(todo);
	  } catch (Exception e) {
	   // TODO: handle exception
	   e.printStackTrace();
	   return result;
	  }
	  return result;
	 }
}

 

위는 todo_list_springMVC 프로젝트의 일부 코드입니다.

사용자가 요청을 하면 @Autowired에 의해 미리 생성된 SqlSessionTemplate가 SqlSession 에 자동주입이 됩니다.

그리고 sqlsession.getMapper(TodoMapper.class);를 호출하는데, 이 부분이 매퍼 인터페이스의 구현 클래스를 얻는 과정입니다.

TodoMapper는 인터페이스로 다형성에 의해 인터페이스형 참조 변수로 구현 클래스를 가리킬 수 있게 됩니다.

 

 TodoMapper mapper = sqlsession.getMapper(TodoMapper.class);
package com.bjy.todolist.dto;

import java.util.List;

public interface TodoMapper {
	public int insertTodo(Todo todo);
	public List<Todo> selectTodo();
	public int updateTodo(Todo todo);
}

 

그러면 getMapper()에 의해 인터페이스 구현 객체가 생성되었으니 구현 클래스의 메소드에 실제 쿼리문을 매핑시키는 과정만 처리하면 됩니다.

int result = mapper.insertTodo(todo);

매핑 인터페이스의 구현 객체의 insertTodo 메소드를 호출하면 이때 매퍼xml 파일을 참고해 이 메소드와 쿼리문을 매핑시키게 됩니다.

그러면 매퍼 xml에 작성된 쿼리문이 DB에서 실행됩니다.

(참고로 Mybatis 환경 설정 파일에도 <mapper> 엘리먼트로 매퍼 xml을 등록하고 사용할 프로퍼티도 미리 선언해야 한다.)

 

TodoMapper.xml (매퍼 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="com.bjy.todolist.dto.TodoMapper">
	<insert id="insertTodo" parameterType="Todo">
	
	insert into todolist
	(
		id
		,title
		,name
		,sequence
		,type
		,regdate
	)
	values
	(
		todoid.nextval
		,#{title}
		,#{name}
		,#{sequence}
		,'TODO'
		,sysdate
	)
	
	</insert>
</mapper>

mybatis-config.xml (Mybatis 환경 설정 파일 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>
	<properties resource="db.properties" />
	<typeAliases>
		<typeAlias type="com.bjy.todolist.dto.Todo" alias="Todo"></typeAlias>
	</typeAliases>
	
	<mappers>
		<mapper resource="mapper/TodoMapper.xml" />
	</mappers>
</configuration>

 

위를 그림으로 대충 정리해보면 다음과 같습니다.

2번에서 SqlSession을 생성한 건 DB와 연결된 상태인 것입니다. 그럼 이제 연결은 됐지만 실제로 쿼리를 날릴 메소드가 필요해지기 때문에 SqlSession으로부터 매퍼 인터페이스 구현 객체를 생성해야 합니다. (getMapper(인터페이스))

 

그렇게 되면 DB에 어떤 쿼리를 날릴 수 있는 객체를 구한 셈입니다.

 

public interface Dao{

  void insert();

}

라는 인터페이스가 있을 때 sqlSession으로부터 getMapper() 메소드를 호출하면 위 Dao 인터페이스를 구현한 클래스를 되돌려줍니다.

예를 들어

 

public class DaoImpl implements Dao{

    void insert();

 

이런 형태의 구현 클래스를 getMapper() 메소드를 통해 가져옵니다. 하지만 여전히 어떤 쿼리문을 실행할지에 대한 내용은 비어있는 상태입니다.

이 내용을 채우기 위해 Mapper XML 파일을 참고해 메소드의 구현부를 DB 쿼리 실행문으로 채우게 됩니다.

즉, 자바의 Mapper 인터페이스 구현한 클래스의 메소드sql문매핑되는 셈입니다. 이때 구현 클래스 자체를 매퍼라고 부릅니다.