JDBC 사용의 불편함
기존에 JSP에서 모든일을 처리했었던걸
이제 MVC패턴까지 적용하면서 완벽하게 5계층으로 나누어졌다.
각 계층별로 정해진 역할을 하면서 확장 및 유지보수에 용이해지도록 했다.
근데 Persistence 계층의 DAO부분에 보면 JDBC를 이용한 코드가 괜히 불편해보인다.
쿼리문을 쓰고 나서 PreparedStatement의 ? 처리
pstmt.setString(i++,freeBoard.getBoTitle());
결과를 Result으로 받고 VO에 하나하나 setting해주기
FreeBoardVO freeBoard = new FreeBoardVO();
freeBoard.setBoNo(rs.getInt("bo_no"));
등의 불편함이 있다.
여기서 '?' 처리도 쉽게하고 쿼리의 결과를 바로바로 VO에 세팅해주는 방법이 있으면
좋겠다는 생각을 할 것이다. 이런 불편함을 해소하기 위한 FrameWork들이 등장했는데
Perstence계층의 불편함을 해소하고,Perstence에서 사용하기 때문에
Persitence FrameWork라 불린다.
Persistence FrameWork
Persisntence FrameWork는 대표적으로 2개의 진영으로 나뉜다.
이 중 SQL Mapper 진영의 Mybatis를 통해
지금까지 JDBC를 통해 DB에 접근했던 DAO부분을 바꿔보자.
※mybatis를 적용하면 기존의 FreeBoardDaoOracle,MemberDaoOracle같은
InterfaceDao의 구현체들은 필요없어진다.
이 구현체들 대신 myabtis의 mapper파일이 실행된다.
또 DB연결도 mybatis 설정파일에서 담당하기때문에
기존의 java.sql.Connection 객체 관련한 코드도 필요없어진다.
즉 DaoOracle, DriverLoader파일은 mybatis 적용 후 필요없다.
mybatis 사용준비
먼저 mybatis를 사용하기 전에 mybatis가 뭔지부터 여러 사용방법에 대해
자세히 작성되어있는 공식 사이트를 소개한다.
https://mybatis.org/mybatis-3/ko/index.html 에 가시면
mybatis를 활용하는데 필요한 대부분의 것들이 정의되어있다.
본 글에서의 과정도 대부분 공식사이트를 참고했다.
우선 mybatis를 적용하기 위해서는 관련 jar파일이 필요하다.
언제나처럼 maven repository사이트에서 mybatis를 검색한다.
원하는 버전을 선택해 다운받는다.
이렇게 jar파일을 추가했으면 mybatis 사용할 준비는 다 끝났다고 할 수 있다.
이클립스 Mybatis 개발 편의 플러그인
이클립스는 기본적으로 mybatis 사용에 관한
편리성 (mybatis관련xml파일, 자동완성 등)을 제공하지 않는다.
따라서 원한할 개발을 위해 편리성을 제공해주는 mybatipse 플러그인을 설치하자.
이클립스 상단의 Help-Eclipse Market place선택 후
검색창에 mybatipse를 검색하고 설치합시다 아래와 같이 생겼다.
이제 준비는 끝났다. 이제 mybatis를 시작하면 된다.
이클립스 Mybatis 개발 편의 플러그인
인텔리제이에서는 MybatisX 플러그인을 설치하자.
mapper파일 생성, 파일이동, 자동완성 등을 지원해준다.
Mybatis의 주요 컴포넌트
mybatis의 주요 컴포넌트를 보고 아래 컴포넌트대로 xml파일과 자바코드를 작성할 것이다.
가장 중요한 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 config 파일
<?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>
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:xe"/>
<property name="username" value="jsp"/>
<property name="password" value="oracle"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mybatis/mapper/freeBoard.xml"/>
</mappers>
</configuration>
settings는 mybatis에 세팅부분인데 지금은 mapUnderScoreToCamelCase를 true로 설정했다.
이는 DB의 mem_id라는 컬럼이 VO에 매핑될 때 자동으로 memId로 매핑되도록 하는 설정이다.
mapUnderScoreToCamelCase외에 여러가지 설정이 있고 자세한 내용은 홈페이지를 참고하자.
entvirometns는 DB에 관한 정보를 담당한다.
mappers의 정의된 mapper는
FreeBoardDaoOracle.java의 메소드가 아닌 mybatis mapper의 쿼리문이 대신 실행된다.
※ configuration태그안에 settings, environments,mapper태그들이
동급이지만 순서는 지켜줘야된다는 것이다.
SqlSessionFactoryBuilder와 SqlSessionFactory
mybatis 홈페이지에는 mybatis config파일을 읽어서
SqlSessionFactory를 만드는 방법 예시가 나와있다.
SqlSessionFactoryBuilder는 SqlSessionFactory를 만드는데 쓰일 뿐이고
SqlSessionFactory는 SqlSession을 제공해주는 역할로서 한개만 만들어도 된다.
Mybatis에서 하나의 트랜잭션 단위는 sqlSession이고
sqlSession은 service의 메소드 실행마다 한개만 있는게 적당하다.
이를 위해 SqlSessionFactory를 만들고 제공해주는 UtilClass를 만들자.
MybatisSqlSessionFactory.java
package com.study.common.util;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class MybatisSqlSessionFactory {
private static SqlSessionFactory sqlSessionFactory;
//DB연결에 관한 모든게 담겨있는 객체
static {
try {
String resource = "mybatis/mybatis-config.xml";
//src밑에 mybatis폴더에 mybatis-config.xml파일이 있어야합니다.
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSessionFactory getSqlSessionFactory() {
return sqlSessionFactory;
}
}
Service에서 SqlSession과 Mapper 객체 사용하기
이제 Service에서 SqlSessionFactory를 얻은 후 SqlSession을 통해 InterfaceDao를 얻어
기존의 DaoOracle.java대신에 mapper에 있는 쿼리문이 실행되도록 설정하자.
FreeBoardServiceImpl.java
public class FreeBoardServiceImpl implements IFreeBoardService {
private SqlSessionFactory sqlSessionFactory = MybatisSqlSessionFactory.getSqlSessionFactory();
@Override
public List<FreeBoardVO> getBoardList() {
try (SqlSession session = sqlSessionFactory.openSession(true)) { // true는 commit, try-with-resources 문법을 활용해서 sqlsession 자동 close
IFreeBoardDao freeBoardDao = session.getMapper(IFreeBoardDao.class);
return freeBoardDao.getBoardList();
}
}
여기서 session을 통해 IFreeBoardDao의 실제객체는 Mybatis가 만들어주는 객체가 된다.
이제 Mybatis가 IFreeBoardDao의 실제객체를 만들 때
개발자가 작성한 Mybatis Mapper파일(.xml)을 참고해 만든다.
Mybatis Mapper파일 만들기
Mybatis 관련 플러그인을 깔았다면 IFreeBoardDao에서 자동완성을 하면 xml을 쉽게 만들 수 있다.
IFreeBoardDao.java
public Interface IFreeBoardDao{
public List<FreeBoardVO> getFreeBoardList();
}
freeBoard.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="IFreeBoardDao의 풀네임(패키지포함명)">
<select id="메소드명" resultType="return타입 풀 네임" parameterType="파라미터타입 풀네임">
원하는 쿼리문 (;제외하기)
</select>
</mapper>
다양한 mapper파일 작성법은 여기를 참고하자.
https://mybatis.org/mybatis-3/sqlmap-xml.html
※ 기존에 JDBC 등을 직접 이용했었다면 OracleDriver를 로드하는 일이나
DBCP등을 만드는 과정을 mybatis가 직접 해준다(mybatis config파일에 설정함).
더 이상 직접 할 필요가 없기 때문에 관련 파일들은 필요없다.