티스토리 뷰

Mybatis 프레임워크는 Spring 이나 Dynamic Web 프로젝트의 DB 연동 작업을 좀 더 쉽게 하기 위해서 탄생한 Apache에서 제작한 프레임워크이다.

 

Mybatis의 가장 중요한 특징은 대표적으로 2가지가 있는데,  첫째는 한두 줄의 자바 코드로 DB 연동을 처리한다는 점이고, 둘째는 SQL 명령어를 자바 코드에서 분리하여 XML 파일에 따로 관리한다는 것이다. 

 

Mybatis 로 DB 연동을 처리하면, 시간을 굉장히 많이 잡아먹는 DB 관련 메서드 작성 시간을 획기적으로 줄일 수 있다.

 

즉, VO 객체와 SQL 명령어를 자동 맵핑까지 해준다는 것!!

 

Mybatis는 xml 파일에 SQL 구문을 따로 관리하기 때문에, 이 구문에 어떤 오류가 있을 경우 IDE 는 에러를 찾을 수 없다는 단점이 있지만, 이 점을 감안하더라도 SQL 구문을 통합하여 관리하는 일은 개발, 유지보수 관점에서 아주 큰 이득이다.

 

간단한 App 예제로 한번 확인해보자.


우선 Mybatis를 사용한 프로젝트를 생성하기 위해, STS(Eclipse) Marketplace에서 MyBatipse 를 다운로드하여 사용해야 한다.


이후 실습을 진행할 새 프로젝트를 생성한 뒤, pom.xml 문서의 dependency를 추가하여 Mybatis 라이브러리를 설치해야한다.

 

◎pom.xml

<!--  Mybatis -->
<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>3.3.1</version>
</dependency>

<!-- Ibatis  -->
<dependency>
  <groupId>org.apache.ibatis</groupId>
  <artifactId>ibatis-core</artifactId>
  <version>3.0</version>
</dependency>


SQL과 맵핑이 될 VO 객체가 있어야 하므로 실습을 위한 BoardVO 또한 이전 프로젝트에서 복사하여 추가하자.

 

◎BoardVO

package com.choonham.biz.board;

import java.util.Date;

public class BoardVO {
	private int seq;
	private String title;
	private String writer;
	private String content;
	private Date regDate;
	private int cnt;
	private String searchCondition;
	private String searchKeyword;

	public BoardVO() {
	}

	public int getSeq() {
		return seq;
	}

	public void setSeq(int seq) {
		this.seq = seq;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getWriter() {
		return writer;
	}

	public void setWriter(String writer) {
		this.writer = writer;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public Date getRegDate() {
		return regDate;
	}

	public void setRegDate(Date regDate) {
		this.regDate = regDate;
	}

	public int getCnt() {
		return cnt;
	}

	public void setCnt(int cnt) {
		this.cnt = cnt;
	}

	public String getSearchCondition() {
		return searchCondition;
	}

	public void setSearchCondition(String searchCondition) {
		this.searchCondition = searchCondition;
	}

	public String getSearchKeyword() {
		return searchKeyword;
	}

	public void setSearchKeyword(String searchKeyword) {
		this.searchKeyword = searchKeyword;
	}

}

 중요한 점은, 자동 맵핑을 위해서는 맴버 변수로 사용되는 클래스의 기본 생성자가 존재해야 하는데, java.sql.Date 클래스는 기본 생성자가 존재하지 않기 때문에 사용할 수 없다는 점이다.


다음에는 DB에 연동할 SQL Mapper XML 파일을 아래 경로에 다음과 같이 생성한다.

파일을 생성하면, 아래와 같이 "mapper" DOCTYPE을 가진 xml 파일이 생성된다.

이후 mapper 파일에 SQL 엘리먼트를 사용하여 구문을 다음과 같이 작성해준다.

 

◎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">
	<insert id = "insertBoard">
		insert into board(seq, title, writer, content)
		values((select nvl(max(seq), 0)+1 from board), #{title}, #{writer}, #{content})
	</insert>
	
	<update id="updateBoard">
		update board set title= #{title}, content=#{content} where seq=#{seq}
	</update>
	
	<delete id="deleteBoard">
		delete board where seq=#{seq}
	</delete>
		
	<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>

이때, 전체 태그를 감싸는 mapper 엘리먼트는 <mapper namespace = "자바 코드에서 사용할 이름"> 과 같이 작성하며, 반드시 프로젝트 전체에서 유일한 이름을 가져야 한다.

 

또한 select문의 resultType에 대한 설정은 myBatis 환경설정 파일에서 설정이 가능하다.


myBatis 는  DB 연동을 DataSource 객체를 이용하여 처리하기 때문에 properties 파일을 하나 생성하여 필요한 정보들을 작성해야 한다.

 

◎src/main/resources/db.properties

jdbc.driverClassName=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@127.0.0.1.1521:XE
jdbc.username=choonham
jdbc.password=6725

이제 이 DateSource, VO, SQL mapper 파일들을 등록하고 설정할 환경 설정 파일인 sql-map-config.xml 파일을 생성해야 한다.

 

생성하는 방법은 mapper.xml 을 생성하는 것과 동일하지만, 생성 이후 다음과 같이 DOCTYPE 설정을 변경하여야 한다.

 

◎sql-map-config.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></configuration>

이 Config 파일의 설정 내용은 다음과 같다.

 

1) properties 파일 설정

2) alias 설정 (자동 맵핑 객체 설정)

3) DataSource 객체 설정(root-context.xml 에서 DI 해줘도 무관하다.)

4) SQL Mapper 설정

 

모두 작성해주면 다음과 같다.

 

◎sql-map-config.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 파일 설정 -->
  <properties resource="db.properties"/>

  <!--  Alias 설정 -->
  <typeAliases>
  	<typeAlias alias="board" type="com.choonham.biz.board.BoardVO"/>
  </typeAliases>

  <!--  DataSource 설정 -->
  <!-- environment 는 여러 개의 DB 접속 내용을 추가로 설정할 수 있다. -->
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value = "${jdbc.driverClassName}"/>
        <property name="url" value = "${jdbc.url}"/>
        <property name="username" value = "${jdbc.username}"/>
        <property name="password" value = "${jdbc.password}"/>
  	  </dataSource>
    </environment>
  </environments>

  <!--  Sql Mapper 설정 -->
  <mappers>
  	<mapper resource="mappings/board-mapping.xml"/>
  </mappers>
</configuration>

sql-map-config 문서를 이용하여 실제로 일을 처리하는 SqlSession 객체를 생성한다.

 

- 자바 코드에서 이 SqlSession 객체를 생성하는 순서는 다음과 같다.

 

1) "sql-map-config.xml" 문서 읽기:

 Reader reader = Resource.getResourceAsReader("읽어들일 환경설정 파일");

 

2) 읽은 문서를 이용하여 SqlSessionFactory 객체를 생성:

  SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(Reader 객체);

 

3) SqlSessionFactory 객체를 통하여 SqlSession 객체를 얻기(생성):

 SqlSession session = SqlSessionFactory 객체.openSession();

 

 

- SqlSession 객체 내부에서 DB 연동을 위해 사용하는 메서드는 다음과 같다.

 

1) insert("Mapper의 nameSpace.해당id", 전달 객체);

 ex) insert("BoardDAO.insertBoard", BoardVO객체);

 

2) update("Mapper의 nameSpace.해당id", 전달 객체);

 

3) delete("Mapper의 nameSpace.해당id", 전달 객체);

 

4) selectOne("Mapper의 nameSpace.해당id", 전달 객체);

 -> 1개의 레코드 반환

 

5) selectList("Mapper의 nameSpace.해당id", 전달 객체)

 -> 2개 이상의 레코드 반환

 

6) commit();

 -> 실제 데이터베이스 수정을 확정하는 메서드


 

이제 DAO 클래스에서 SqlSessionFactory객체 생성을 위한 메서드를 선언하기 위해 SqlSessionFactoryBean 클래스를 작성하여, sql-map-config.xml 설정 파일을 읽어 SqlSessionFactory객체 생성을 위임한다.

 

◎SqlSessionFactoryBean.java

package com.choonham.biz.util;

import java.io.Reader;

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 SqlSessionFactoryBean {

  private static SqlSessionFactory sessionFactory = null;

  //static 변수에 대한 초기값 설정
  static {
    try{
      if(sessionFactory == null) {
        Reader reader = Resources.getResourceAsReader("sql-map-config.xml");
        sessionFactory = new SqlSessionFactoryBuilder().build(reader);
    	}
    } catch(Exception e){
    	e.printStackTrace();
    }
  }
  //DAO 클래스에서 호출 할 메서드
  public static SqlSession getSqlSessionInstance() {
  	return sessionFactory.openSession();
  }
}

이제 실제로 myBatis를 이용하여 DB 연동을 수행할 DAO 클래스를 작성하자.

 

◎BoardDAO

package com.choonham.biz.board.impl;

import java.util.List;

import org.apache.ibatis.session.SqlSession;

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

public class BoardDAO {

	private SqlSession mybatis;
	
	//SqlSessionFactory 객체 생성
	public BoardDAO() {
		mybatis = SqlSessionFactoryBean.getSqlSessionInstance();
	}
	
    	//mybatis.insert("Mapper의 nameSpace.해당id", 전달 객체)
	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);
	}
}

이후 테스트를 위한 Client 코드를 작성해준 뒤, 확인해보면

 

◎client

package com.choonham.biz.board;

import java.util.List;

import com.choonham.biz.board.impl.BoardDAO;

public class BoardServiceClient {

	public static void main(String[] args) {
		BoardDAO boardDAO = new BoardDAO();
		
		BoardVO vo = new BoardVO();
		vo.setTitle("myBatis");
		vo.setWriter("홍길동");
		vo.setContent("myBatis 내용입니다.");
		boardDAO.insertBoard(vo);
		
		vo.setSearchCondition("TITLE");
		vo.setSearchKeyword("");
		
		List<BoardVO> boardList = boardDAO.getBoardList(vo);
		
		for(BoardVO board : boardList) {
			System.out.println(board.toString());
		}
		
	}

}

정상 동작하는 것을 확인할 수 있다.

 

xml 파일들을 설정하는 작업이나, 좀 생소한 객체들이 나와서 낯설지만, DB 연동에 필요한 많은 줄의 코드를 획기적으로 줄일 수 있는, 효율적이 개발이 Mybatis를 활용하면 가능하다.

'[JAVA] > Mybatis' 카테고리의 다른 글

[Mybatis] SQL 쿼리문을 실행하는 두가지 방법  (0) 2021.07.01
[Mybatis] JavaORM plugin  (0) 2021.06.30
[Mybatis] Dynamic SQL  (0) 2021.06.30
[Spring] Mybatis 사용  (0) 2021.06.29
[Mybatis] Mapper Elements  (0) 2021.06.29
Comments