[MyBatis] MyBatis


MyBatis는 iBATIS의 새로운 버전으로 한국에서 가장 널리 사용되는 ORM 프레임워크 중 하나입니다. MyBatis는 잘 문서화되어 있지만 이전 iBATIS 버전과 비교하여 실제로 사용하기 위한 예제가 부족합니다. 그래서 간단한 예제를 작성하여 자료를 정리하고 참고자료를 만들어 보겠습니다. 먼저 MyBatis를 설정하고 간단한 예제를 수행한 다음 Spring 3에 빈을 등록하는 예제로 확장할 계획입니다.

MySQL 테이블

CREATE TABLE user (
 id INT(5) NOT NULL PRIMARY KEY AUTO_INCREMENT,
 username VARCHAR(16) NOT NULL,
 password VARCHAR(16) NOT NULL,
 level INT(2) NOT NULL DEFAULT '0',
 reg_date DATE NOT NULL
);

건설

발달.특성

url=jdbc:mysql://localhost/development?characterEncoding=utf-8
driver=com.mysql.jdbc.Driver
user=development
pass=test123

mysql-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 resource="exercise/mybatis3/persistence/development.properties"/>
 
 <settings>
  <setting name="defaultExecutorType" value="REUSE"/>
  <setting name="useGeneratedKeys" value="true"/>
 </settings>
 
 <typeAliases>
 <!-- Type Aliases List --> 
 </typeAliases>
 
 <environments default="development">
  <environment id="development">
   <transactionManager type="JDBC"/>
   <dataSource type="JNDI">
    <property name="initial_context" value="java:comp/env" />
    <property name="data_source" value="jdbc/insure"/>
   </dataSource>
  </environment>
  
  <environment id="testing">
   <transactionManager type="MANAGED">
    <property name="closeConnection" value="false"/>
   </transactionManager>
   <dataSource type="POOLED">
    <property name="driver" value="${driver}" />
    <property name="url" value="${url}" />
    <property name="username" value="${user}" />
    <property name="password" value="${pass}" />
   </dataSource>
  </environment>
 </environments>
 
 <mappers>
 <!-- Mapper List -->
 </mappers>
</configuration>

SQL 매퍼

UserMapper.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="exercise.mybatis3.persistence.UserMapper">
 <insert id="add" parameterType="User"
   useGeneratedKeys="true" keyProperty="id">
  INSERT INTO user (username, password, level, reg_date)
  VALUES (#{username}, #{password}, 1, NOW())
 </insert>
 
 <select id="count" resultType="int">
  SELECT COUNT(*) FROM user
 </select>
</mapper>

UserMapper.java

package exercise.mybatis3.persistence;

import exercise.mybatis3.domain.User;

public interface UserMapper {
	public void add(User user);

	public int count();
}

도메인 객체

사용자.자바

package exercise.mybatis3.domain;

import java.io.Serializable;

public class User implements Serializable {
	private static final long serialVersionUID = 1L;
	private Integer id;
	private String username;
	private String password;
	private Integer level;
	private String regDate;

	public User() {
		// TODO Auto-generated constructor stub
	}

	public User(String username, String password) {
		this.username = username;
		this.password = password;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public Integer getLevel() {
		return level;
	}

	public void setLevel(Integer level) {
		this.level = level;
	}

	public String getRegDate() {
		return regDate;
	}

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

장치 테스트

TestUserMapper.java

package exercise.mybatis3.test;

import static org.junit.Assert.assertThat;
import static org.hamcrest.CoreMatchers.is;

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;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import exercise.mybatis3.domain.User;
import exercise.mybatis3.persistence.UserMapper;

public class TestUserMapper {
	static SqlSessionFactory sf;
	User user;

	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		String resource = "exercise/mybatis3/persistence/mybatis-config.xml";
		Reader reader = Resources.getResourceAsReader(resource);
		sf = new SqlSessionFactoryBuilder().build(reader, "testing");
	}

	@Before
	public void setUp() {
		user = new User("user1", "1234");
	}

	@Test
	public void testAdd() {
		SqlSession session = sf.openSession();
		try {
			UserMapper mapper = session.getMapper(UserMapper.class);
			mapper.add(user);
			assertThat(1, is(mapper.count()));
		} finally {
			session.close();
		}
	}
}

SQL 매퍼(CRUD)

UserMapper.xml

<mapper namespace="exercise.mybatis3.persistence.UserMapper">
 <insert id="add" parameterType="User"
   useGeneratedKeys="true" keyProperty="id">
  INSERT INTO user (username, password, level, reg_date)
  VALUES (#{username}, #{password}, #{level}, #{regDate})
 </insert>
 
 <select id="get" parameterType="int" resultType="User">
  SELECT
   id, username, password, level, reg_date AS 'regDate'
  FROM user
  WHERE id = #{id}
 </select>
 
 <select id="getAll" resultType="User">
  SELECT
   id, username, password, level, reg_date AS 'regDate'
  FROM user
 </select>
 
 <delete id="delete" parameterType="int">
  DELETE FROM user
  WHERE id = #{id}
 </delete>
 
 <delete id="deleteAll">
  DELETE FROM user
 </delete>
 
 <select id="count" resultType="int">
  SELECT COUNT(*) FROM user
 </select>
 
 <select id="lastId" resultType="int">
  SELECT id
  FROM user
  ORDER BY id DESC
  LIMIT 1
 </select>
</mapper>

CRUD(매퍼 인터페이스 클래스)

UserMapper.java

public interface UserMapper {
	public void add(User user);
	public User get(int id);
	public List<user> getAll();
	public void delete(int id);
	public void deleteAll();
	public int count();
	public int lastId();
}

도메인 객체

사용자.자바

public class User implements Serializable {
	private static final long serialVersionUID = 1L;
	private Integer id;
	private String username;
	private String password;
	private Integer level;
	private String regDate;

	public User() {
		// TODO Auto-generated constructor stub
	}

	public User(String username, String password, Integer level, String regDate) {
		this.username = username;
		this.password = password;
		this.level = level;
		this.regDate = regDate;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public Integer getLevel() {
		return level;
	}

	public void setLevel(Integer level) {
		this.level = level;
	}

	public String getRegDate() {
		return regDate;
	}

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

	@Override
	public boolean equals(Object comp) {
		User target = (User) comp;
		if (this.id.equals(target.id) && this.username.equals(target.username) && this.password.equals(target.password) && this.level.equals(target.level) && this.regDate.equals(target.regDate))
			return true;
		else
			return false;
	}
}

단위 테스트(CRUD)

TestUserMapper.java

public class TestUserMapper {
 static SqlSessionFactory sf;
 List<user> users;

 @BeforeClass
 public static void setUpBeforeClass() throws Exception {
  String resource =
    "exercise/mybatis3/persistence/mybatis-config.xml";
  Reader reader = Resources.getResourceAsReader(resource);
  sf = new SqlSessionFactoryBuilder().build(reader, "testing");
  
 }
 
 @Before
 public void setUp() {
  users = Arrays.asList(
    new User("user1", "1234", 1, "2012-11-09"),
    new User("user2", "1234", 1, "2012-11-09"),
    new User("user3", "1234", 1, "2012-11-09")
  );
 }

 @Test
 public void testAdd() {
  SqlSession session = sf.openSession();
  
  try {
   UserMapper mapper = session.getMapper(UserMapper.class);
   
   mapper.deleteAll();
   
   mapper.add(users.get(0));
   assertThat(1, is(mapper.count()));
  } finally {
   session.close();
  }
 }
 
 @Test
 public void testGet() {
  SqlSession session = sf.openSession();
  
  try {
   UserMapper mapper =
      session.getMapper(UserMapper.class);
   
   mapper.deleteAll();
   mapper.add(users.get(0));
   
   User user = mapper.get(mapper.lastId());
   
   assertTrue((users.get(0)).equals(user));
  } finally {
   session.close();
  }
 }
 
 @Test
 public void testGetAll() {
  SqlSession session = sf.openSession();
  
  try {
   UserMapper mapper =
      session.getMapper(UserMapper.class);
   
   mapper.deleteAll();
   for (User user : users) {
    mapper.add(user);
   }
   
   assertThat(users.size(), is(mapper.count()));
  } finally {
   session.close();
  }
 }
 
 @Test
 public void testDelete() {
  SqlSession session = sf.openSession();
  
  try {
    UserMapper mapper =
      session.getMapper(UserMapper.class);
    
    mapper.deleteAll();
    for (User user : users) {
     mapper.add(user);
    }
    mapper.delete(mapper.lastId());
    
    assertThat(users.size() - 1, is(mapper.count()));
   } finally {
    session.close();
   }
  }
 }
}