Programming/JPA ⁄Spring

JDBC 와 MYSQL 연동하기 7) MyBatis 적용하기

📝 작성 : 2021.04.17  ⏱ 수정 : 
반응형

Mybatis란?

Mybatis는 Java Persistence Framework 입니다. SQL 문장을 XML 혹은 어노테이션을 이용해 Object에 저장하도록 해줍니다. 

ORM ( Object Relational Mapping)

혹은 Sql Mapper Framework 로 불립니다. Transaction 도 관리해주며, class loader 형태로 접근(절대경로)합니다.

Ibatis가 발전해 MyBatis가 되었는데요,  Apache Project 팀에서 google code 팀으로 이동하며 명칭이 변경되었습니다.

MyBatis와 Ibatis는 몇가지 차이점이 있습니다.

- IBatis는 JDK 1.4 에서 사용이 가능합니다. MyBatis로 넘어오며 요구사항이 JDK 1.5 이상으로 바뀌었습니다.

- namespace의 사용이 선택에서 필수로 바뀌었습니다. 인터페이스의 qualified name을 namespace로 사용하며 자체적으로 리플렉션 됩니다. 

- Annotation의 사용이 도입되었습니다. 또한 SqlSessionFactory를 사용합니다.


Eclipse에서는 MyBaptise 플러그인을 설치해서 사용합니다.

 

1. 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="dbinfo.properties"/>
	<typeAliases>
		<package name="kr.or.ddit.vo"/>
	</typeAliases>
	<environments default="dev">
		<environment id="dev">
			<transactionManager type="JDBC"/>
			<dataSource type="POOLED">
				<property name="driver" value="${driverClassName}"/>
				<property name="url" value="${url}"/>
				<property name="username" value="${user}"/>
				<property name="password" value="${password}"/>
			</dataSource>
		</environment>
	</environments>
	<mappers>
		<mapper resource="mybatis/mappers/Alba.xml"/>
	</mappers>
</configuration>

mapper 파일도 바로 만들 예정이기 때문에 mapper도 미리 등록해두었습니다.

 

2. SqlSessionFactory 만들기

package kr.or.ddit.db.mybatis;

import java.io.IOException;
import java.io.Reader;

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

public class CustomSqlSessionFactoryBuilder {
	private static SqlSessionFactory sessionFactory;
	
	static {
		String xmlRes = "mybatis/config.xml";
		try(
			Reader reader = Resources.getResourceAsReader(xmlRes);
			// 한글을 읽을 수도 있으니 굳이 리더로 해야한다.
		) {
			sessionFactory = new SqlSessionFactoryBuilder().build(reader);
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}
	
	public static SqlSessionFactory getSessionFactory() {
		return sessionFactory;
	}
}

위에서 만든 config.xml 파일을 읽어 SqlSession을 만들어 주는 Factory입니다. 위에서 만든 config.xml에 한글이 없지만 혹시 한글이 들어갈 일이 있을 수 있으니 굳이 Reader로 읽었습니다. 자체적으로 Builder 패턴을 사용합니다.

3. mapper 파일 만들기

처음 MyBatis XML Mapper 파일을 만들면 위와 같이 생성되는데요,

항상 제일 먼저 namespace를 변경해줘야 합니다.

 

 

DAO Interface 파일의 Qualified Name을 copy한뒤에 ClassPath 형태로 namespace를 지정해줍니다.

/alba/src/main/java/kr/or/ddit/dao/AlbaDAO.java 가 복사되었는데 아래와 같이 변경해줍니다.

select 키도 하나 등록하며 기존의 DAO 에서 사용하던 쿼리를 그대로 사용합니다.

<?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="kr.or.ddit.dao.AlbaDAO">
	<select id="selectAlbaList" parameterType="PagingVO" resultType="AlbaVO">
		SELECT *
		FROM ALBA
	</select>
</mapper>

 

이제 마지막으로 Dao를 변경해줍니다. 원래는 아래 코드였습니다.

public List<AlbaVO> selectAlbaList(PagingVO<AlbaVO> pagingVO) {
		List<AlbaVO> albaList = new ArrayList<>();
		try(
			Connection conn = ConnectionFactory.getConnection();
		){
			String sql = "select * from alba";
			Statement statement = conn.createStatement();
			ResultSet result = statement.executeQuery(sql);

			while(result.next()) {
				AlbaVO alba = new AlbaVO();
				
				String al_id = result.getString(1);
				String al_name = result.getString(2);
				int al_age = result.getInt(3);
				String al_zip = result.getString(4);
				String al_addr1 = result.getString("al_addr1");
				String al_addr2 = result.getString("al_addr2");
				String al_hp = result.getString("al_hp");
				String gr_code = result.getString("gr_code");
				String al_gen = result.getString("al_gen");
				String al_mail =result.getString("al_mail");
				String al_career = result.getString("al_career");
				String al_spec = result.getString("al_spec");
				String al_desc = result.getString("al_desc");
				String al_img = result.getString("al_img");
				
				alba.setAl_id(al_id);
				alba.setAl_name(al_name);
				alba.setAl_age(al_age);
				alba.setAl_zip(al_zip);
				alba.setAl_addr1(al_addr1);
				alba.setAl_addr2(al_addr2);
				alba.setAl_hp(al_hp);
				alba.setGr_code(gr_code);
				alba.setAl_gen(al_gen);
				alba.setAl_mail(al_mail);
				alba.setAl_career(al_career);
				alba.setAl_spec(al_spec);
				alba.setAl_desc(al_desc);
				alba.setAl_img(al_img);
				
				albaList.add(alba);
				
			}
		} catch (SQLException e) {
			e.printStackTrace();

		}
		return albaList;
	}

 

selectAlbaList 메소드만 해도 저렇게 길었는데 

	public List<AlbaVO> selectAlbaList(PagingVO<AlbaVO> pagingVO) {
		try(
			SqlSession session = sessionFactory.openSession();
		){
			AlbaDAO mapper = session.getMapper(AlbaDAO.class);
			return mapper.selectAlbaList(pagingVO);
		}
		
	}

MyBatis를 사용하니 위와 같이 짧아집니다. session은 close 되어야 하니 try with resources Statement 로 작성해주는걸 잊으면 안됩니다!

 

아래는 새로 만든 AlbaDAOImpl 전체 코드입니다.

package kr.or.ddit.dao;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

import kr.or.ddit.db.mybatis.CustomSqlSessionFactoryBuilder;
import kr.or.ddit.vo.AlbaVO;
import kr.or.ddit.vo.PagingVO;

public class AlbaDAOImpl implements AlbaDAO {
	private static AlbaDAOImpl self;
	private AlbaDAOImpl() {};
	
	private SqlSessionFactory sessionFactory = CustomSqlSessionFactoryBuilder.getSessionFactory();
	
	public static AlbaDAOImpl getInstance() {
		if(self == null) self = new AlbaDAOImpl();
		return self;
	}
	
	@Override
	public List<AlbaVO> selectAlbaList(PagingVO<AlbaVO> pagingVO) {
		try(
			SqlSession session = sessionFactory.openSession();
		){
			AlbaDAO mapper = session.getMapper(AlbaDAO.class);
			return mapper.selectAlbaList(pagingVO);
		}
		
	}

	@Override
	public AlbaVO selectAlba(String al_id) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public int insertAlba(AlbaVO alba) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int updateAlba(AlbaVO alba) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int selectTotalRecord(PagingVO<AlbaVO> pagingVO) {
		// TODO Auto-generated method stub
		return 0;
	}

}

 

MyBatis는 Persistence Layer와 DB 사이에서 동작하기 때문에, 코드의 변화는 Persistence Layer인 DAO에만 있으며 다른 Layer의 코드는 그대로 사용하면 됩니다. 

이제, MyBatis 적용이 잘 되었는지 테스트를 마지막으로 해보면, 코드는 훨씬 간결해졌지만 결과에는 변화가 없음을 확인 할 수 있습니다.

 

이제 개발에 필요한 모든 준비는 끝났습니다. Layer가 나누어져있기 때문에 협업도 가능합니다.

반응형