개발자가 지정한 SQL저장 프로시저 및 고급 Mapping을 지원하여 개발 생산성을 높이는 Persistence Framework
Java에서 DB 프로그래밍을 하기 위하여 JDBC
를 제공한다. 다양한 API를 제공하지만 점차 데이터가 방대해지고 각 데이터들의 관계가 복잡해지면서 다수의 메서드를 호출하고 관련 객체를 호출 및 해제해야하는 문제점이 빈번하게 발생하게 된다. 이러한 문제점을 해결하고, 더욱 효과적으로 DB를 관리하기 위해 Mybatis
가 등장했다.
기존 JDBC만을 이용한 DB 프로그래밍 방식은 프로그램 소스안에서 직접 연결(Connection)
을 맺고, 쿼리문을 수행하고, 다시 반납하기를 반복하면서 비슷한 성격의 코드를 작성하는데 있어서 효과적이지 못했다. 또한, 코드가 길어
지고 유지보수 측면에서 java 프로그램 자체를 수정하기 때문에 코드의 유연성
이 좋지 못하다. 아래 코드를 보자.
//insert문 수행예시
public int insert(Gallery gallery) {
int result = 0;
Connection conn = null;
PreparedStatement pstmt = null; //쿼리수행 객체 생성
conn = pool.getConnection(); //메서드 내부에서 Connection 연결
String sql = "insert into gallery(gallery_idx, title, writer, content, filename)";
sql += " values(seq_gallery.nextval, ?, ?, ?, ?)";
//쿼리문 작성
try {
pstmt = conn.prepareStatement(sql); //쿼리문 수행
//바인드변수 연결
pstmt.setString(1, gallery.getTitle());
pstmt.setString(2, gallery.getWriter());
pstmt.setString(3, gallery.getContent());
pstmt.setString(4, gallery.getFileName());
result = pstmt.executeUpdate(); //결과 반환
} catch (SQLException e) {
e.printStackTrace();
} finally {
pool.release(conn, pstmt); //사용자원 반납
}
return result;
}
반면 Mybatis를 사용할 경우 상당부분의 코드와 파라미터 설정
등과 쿼리문 결과에 대한 처리를 대신해주어 코드의 중복
을 방지하고 간소화된 코드
를 작성하는 효과가 있다. 또한, 수정이 필요한 경우 xml 파일
에 작성된 쿼리문만 수정하면 되기에 변환이 자유롭고 가독성이 좋아진다. Mybatis로 작성한 아래 코드를 보자.
public int insert(Board board) {
//싱글턴 패턴을 이용해 세션 객체 호출
SqlSession session = config.getSqlSession();
//xml에 쿼리문을 기반으로 메서드 실행
int result = session.insert("board.insert", board);
//쿼리문 트랜잭션 확정
session.commit();
//세션 객체 반납
config.release(session);
return result;
}
위의 두 코드를 눈으로만 봐도 코드가 간결해지고 쿼리문과 분리되어있다는 것이 보일 것이다. 이러한 이유로 프로젝트가 크면 클수록 Mybatis를 이용하는 것이 좋다.
파라미터 설정
및 결과 매핑 기능
을 대신해준다.xml파일
에 작성되어 유지되므로 가독성이 좋다.재사용성
이 좋다.POJO(Plain Old Java Object)
를 데이터베이스 레코드에 매핑이 가능하다.유지보수성
을 높일 수 있다.자동 Mapping
해준다.이제 본격적으로 Mybatis를 사용하는 방법에 대해서 알아보자.
가장 먼저 해야할 일은 'maven repository'에 접속하여 maven dependency
로 등록해 줄 mybatis를 다운받는 것이다. 아래 경로로 들어가 다운을 받아주자. 참고로 나는 3.4.6 버전을 받았다.
maven repository 경로
https://mvnrepository.com/artifact/org.mybatis/mybatis
아래의 사진에서 처럼 다운받고 싶은 버전을 클릭하면 된다.
만약 maven repository 접속이 불가능하다면 아래 코드를 복사해서 사용하여도 무방하다.
위 그림에서 처럼 maven의 pom.xml
파일을 열어 해당 코드를 입력하고 저장을 해주면 된다. 저장이 완료되었다면 프로젝트 내 maven라이브러리
에 mybatis가 포함되어있는지 확인하자. 포함되어있다면 정상적으로 설치가 된 것이다.
설치가 완료되었으니 이제 이클립스에서 사용을 해보겠다.
가장 먼저 해야하는 것은 선택사항이지만 있으면 편한 플러그인
을 설치하는 것이다. 아래 설명한 방법을 따라 들어가 설치를 진행하자.
이클립스 'help' 탭에서 'marketplace' 클릭하여 접속
'mybatis' 검색 후 두번째에 보이는 'mybatipse' 플러그인 설치 후 이클립스 재시작
새 xml파일 생성에서 사진과 동일한 파일을 선택 후 파일명 지정(환경설정이라는 의미에서 config.xml로 생성하였다.) 후 공식홈페이지의 xml 형식 붙여넣어준다.
공식홈페이지의 xml 양식 경로
https://mybatis.org/mybatis-3/getting-started.html
그림에서 보이는 것처럼 property 영역
의 각 value들을 자신이 사용중인 JDBC 환경에 맞게 수정해주면된다. 나는 Oracle을 사용하기 때문에 Oracle에 대한 DB연결 정보를 입력하였다.
이제 DAO와 1:1로 대응하는 xml을 매핑해주어야한다. 나는 테이블명이 Board이기 때문에 BoardMapper라고 xml 파일을 생성하고 맵핑해주었다. 여기서 매핑을 해주어야 Mybatis가 해당 연결정보에서 매핑된 xml을 기반으로 쿼리문을 수행할 수 있도록 도와준다.
매핑을 완료해준 뒤 생성한 xml로 돌아와 parameterType을 지정해준다. 여기서 사용되는 parameter는 DTO이다. 위에서 설명한 POJO의 일부이다. 반드시 ""
내에 패키지명
과 클래스의 이름
을 정확하게 입력하여 주어야한다.
다음으로 해당 xml에서 실행할 쿼리문
을 작성한다. 예시로 insert에 대해서 쿼리문을 작성하였다. values에 들어가는 각 컬럼의 값은 parameter
로 매핑된 Board의 멤버변수
로 넘겨받는다. 즉, values에서 각 컬럼에 들어가는 값은 DTO의 멤버변수
와 동일한 이름이어야한다.
기존의 JDBC에서 바인드변수가 차지하던 자리를 매핑된 DTO의 멤버변수가 차지하는 것이다.
이제 xml의 준비는 끝났다. Java에서 생성한 DAO에서 mybatis를 parsing해보자.
아래 코드는 mybatis 공식홈페이지에 있는 SqlSessionFactory
를 생성하는 코드이다. SqlSession
은 기존 JDBC에서 Connection 및 PreparedStatement 등의 역할을 하는 객체로 메서드 내에서 계속 새로운 연결이 필요하다면 기존과 mybatis가 다를 것이 없을 것이다. 이러한 부분을 해결하기 위해 아래 공식홈페이지의 설명도 함께 보자.
String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
공식홈페이지의 설명을 읽어보면 '싱글톤 패턴'
으로 생성하는 것을 권장하고 있다. 그렇다면 클래스로 싱글톤 패턴
을 적용하여 만들면서 Connection Pool
을 사용하는 것처럼 Factory
에서 SqlSession
을 필요할때 꺼내서 사용할 수 있도록 클래스를 구성해볼 것이다. 주의 해야하는 점은 Sqlsession은 매 요청마다 얻어오고 반납을 반복해줘야함. 즉, 멤버변수 등으로 보유
하거나, 참조
를 엮지 말아야한다는 점이다.
다음 코드는 싱글톤 패턴을 적용한 SqlSessionFactory 생성 클래스이다.
//SqlSessionFactory를 싱글턴 패턴으로 관리하기 위한 클래스
public class MybatisConfig {
//싱글톤 패턴을 위한 인스턴스 선언
private static MybatisConfig instance;
//인스턴스가 보유할 Factory 선언
SqlSessionFactory sqlSessionFactory;
private MybatisConfig() {
// DB 연결 및 Mapper 정보(본인이 설정한 패키지 경로와 파일명 입력)
String resource = "board/mybatis/config.xml";
// 순수 JDBC 코드의 쿼리실행 객체 = PreparedStatement
// Mybatis는 JDBC를 매핑해서 쿼리를 실행 = SqlSession
try {
// 로컬의 xml파일을 읽어드리기
InputStream inputStream = Resources.getResourceAsStream(resource);
// 생성자를 통해 인스턴스가 생성될 때 Factory 생성
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
//SqlSession을 반환해주는 메서드
public SqlSession getSqlSession() {
return sqlSessionFactory.openSession();
}
//SqlSession을 반납하는 메서드
public void release(SqlSession sqlSession) {
if(sqlSession != null) {
sqlSession.close();
}
}
//인스턴스 생성 메서드
public MybatisConfig getInstance() {
if (instance == null) {
instance = new MybatisConfig();
}
return instance;
}
}
//insert문 예시
public int insert(Board board) {
//싱글턴 패턴을 이용해 세션 객체 호출
SqlSession session = config.getSqlSession();
//xml에 쿼리문을 기반으로 메서드 실행
int result = session.insert("board.insert", board);
//쿼리문 트랜잭션 확정
session.commit();
//세션 객체 반납
config.release(session);
return result;
}
위에서 비교에 사용한 코드와 동일한 코드다. 메서드를 실행할 때 SqlSession을 Factory 인스턴스(config)로부터 받아오며 해당 쿼리문을 수행하고 트랜잭션을 확정지은 뒤 반납한다. 쿼리문이 수정되는 경우에는 xml파일로 이동하여 쿼리문만 수정해주면 되기 때문에 유지보수 및 코드의 분리와 재사용 측면에서 훨씬 유연해졌다고 할 수 있다.
설치 및 사용에 대하여 알아보았으니 마지막으로 동작원리에 대해서 알아보고 마무리하자.
위 그림을보면 동작원리는 두가지로 나뉜다. 먼저 어플리케이션 실행 시 수행되는 프로세스
가 상단 부분이며, 그 다음은 어플리케이션이 실행되는 동안 클라이언트의 요청 시 수행되는 프로세스
이다. 프로세스별 동작순서 및 원리를 간단하게 표현해보겠다.
기존 JDBC를 사용할 때보다 코드의 분리로 인한 가독성이 확실히 좋아졌다. 또한, 코드가 간소화되어 이전에 반복적인 코드들이 간소화되고 생산성이 올라간 것이 느껴진다. 아직 공부해야 할 부분은 많지만 왜 사용하는지에 대해서는 확실히 알 수 있었다.
이번 글에서는 수업에 배운 내용을 바탕으로 Mybatis의 기초적인 부분들을 작성하였다. 혹시 틀리거나 잘못된 부분이 있다면 이야기해주길 바란다.
https://velog.io/@jonghne/MyBatis-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC
https://mybatis.org/mybatis-3/index.html
https://hyejin.tistory.com/261