[DB] MyBatis vs JPA
백엔드에서 데이터베이스를 사용하는 프레임워크로 가장 많이 쓰이는 기술이 'Mybatis'와 'JPA'입니다.
Java 기반의 Spring 또는 SpringBoot에서 데이터베이스를 사용하려면 두 가지 기술 중 하나를 사용해야 하기 때문에 Java 백엔드 개발자는 'Mybatis'와 'JPA'를 반드시 알고 있어야 합니다.
데이터베이스 접속을 편하게 사용하기 위해 SQL Mapper 기술과, ORM(Object Relational Mapping) 기술을 제공합니다.
- SQL Mapper : '개발자가 작성한 SQL 실행 결과를 객체에 매핑'시켜주는 프레임워크 -> MyBatis
- ORM : 객체와 DB의 데이터를 '자동으로 매핑'시켜주는 프레임워크 -> JPA(Java Persistence Api)
두가지 기술은 모두 데이터를 관계형 데이터베이스에 저장, 즉 영속화(Persistence) 시킨다는 측면에서는 동일하지만, 서로 다른 접근 방식을 채택하고 있습니다.
MyBatis
MyBatis 프레임워크는 반복적인 JDBC 프로그래밍을 단순화하여, 불필요한 비슷하고 반복적인 코드를 제거하고, Java 소스코드에서 SQL문을 분리하여 별도의 XML 파일을 저장하고, 이 둘을 서로 연결시켜주는 기능을 제공합니다.
MyBatis의 특징
Java 코드와 SQL 매핑
MyBatis를 사용하면, MyBatis 내부에서 그러한 반복적인 코드가 구현되어 있고, MyBatis에서 Java메소드와 SQL 간에 매핑을 시켜서 개발자는 Java 메소드 선언과 SQL문만 만들면 MyBatis가 자동으로 그 둘 간을 연결시켜 주게 됩니다.
SQL문을 별도로 Java코드에서 분리해두어서 관리가 편한 장점이 있으며, 분리된 SQL문을 MyBatis가 찾아서 실행해 주는 기능을 합니다.
MyBatis 프레임워크는 반복적인 JDBC 프로그래밍을 단순화하여, 불필요하고 반복적인 코드를 제거하고, Java 소스코드에서 SQL문을 분리하여 별도의 XML 파일로 저장하고, 이 둘을 서로 연결시켜주는 기능을 제공합니다.
@Mapper
public interface BoardMapper{
List<BoardDTO> selectPerson();
...
}
<mapper namespace="com.example.demo.mapper.BoardMapper">
<select id="selectPerson" parameterType="int" resultType="BoardDTO">
SELECT * FROM PERSON WHERE ID = #{id}
</select>
...
동적 SQL 생성 기능
MyBatis는 반복적인 코드 제거 및 SQL문 분리 외에도 동적인 SQL(Dynamic SQL) 생성 기능을 제공하여 프로그램 실행 중에 입력되는 파라미터에 따라 서로 다른 SQL 문을 동적으로 생성해 내는 기능을 제공해 줍니다.
동적으로 SQL문이 생성된다는 의미는 검색 조건같이 사용자가 입력하는 값에 따라 서로 다른 SQL 문장이 생성되어 실행된다는 의미입니다.
예를 들어, 게시판 테이블을 검색할 때, 사용자가 작성자만 입력하여 검색하면 작성자가 WHERE 절에 있는 다음의 SQL이 생성됩니다.
- SELECT * FROM BOARD WHERE AUTHOR = '파라미터'
제목을 입력하여 검색하면 다음과 같이 제목을 검색하는 SQL이 만들어집니다.
- SELECT * FROM BOARD WHERE TITLE LIKE '%파라미터%'
MyBatis 내에 if문, choose, when, otherwise, foreach 등의 문법을 지원해서 동적인 SQL문 생성이 가능합니다.
아래 예시에서는 title 파라미터를 입력받게 되면 SQL문이 아래와 같이 생성되고,
- SELECT * FROM BLOG WHERE state = 'active' AND title like #{title}
title 파라미터 없이 호출이 되는 경우엔, 아래와 같이 title 조건이 없는 SQL문이 생성됩니다.
- SELECT * FROM BLOG WHERE state = 'active'
MyBatis의 장점, 단점
장점:
- 접근이 쉽고 코드가 간결하다.
- SQL문과 프로그래밍 코드가 분리되어 있어서 SQL문에 변경이 있을때마다 자바 코드를 수정하거나 컴파일 하지 않아도 된다.
- 다양한 프로그래밍 언어로 구현이 가능하다.
단점:
- 스키마 변경시 SQL 쿼리를 직접 수정해주어야 한다.
- 반복된 쿼리가 발생하여 반복 작업이 있다.
- 쿼리를 직접 작성하기 때문에 데이터베이스에 종속된 쿼리문이 발생할 수 있다.
- 데이터베이스 변경시 로직도 함께 수정해주어야 한다.
JPA는 이보다 한발 더 나아가서 SQL문까지 자동으로 생성해주고, DB 데이터와 Java 객체를 매핑 시켜주는 기술입니다. SQL 문장 작성이 필요 없으니 MyBatis보다 한 단계 더 자동화되어 더 편리함과 반복작업을 없애줍니다.
JPA란?
JPA(Java Persistence API)는 Java 객체와 관계형 데이터베이스 간의 매핑을 위한 API입니다. JPA는 ORM(Object-Relational Mapping)을 구현하는 자바 표준 스펙으로, 개발자가 객체지향 프로그래밍 언어에서 사용하는 객체 모델과 관계형 데이터베이스의 테이블 간의 매핑을 자동으로 처리해 줍니다.
MyBatis와 차이
JPA는 MyBatis와 같이 SQL문과 Java코드를 연계하는 접근 방식이 아니라 Java 객체와 DB 엔티티(테이블) 자체를 그대로 매핑해서 처리할 수 있는 접근 방식입니다.
JPA의 접근 방식은 이런 ORM(Object-Relational Mapping) 기술을 의미합니다. 즉 객체와 데이터베이스 간의 매핑 기술을 의미하며, Java 개발자가 좀 더 객체지향 관점에서 개발할 수 있게 하고, 개발을 용이하게 해주어서 DB와 Java 간의 불일치를 해소해줍니다.
이러한 ORM 기술을 실제 구현해서 만들어진 프레임워크가 Hibernate입니다. JPA 스펙을 구현한 기술은 Hibernate 외에도 EcliseLink, DataNucleus 등이 있지만, 현재 사실상 표준으로 널리 사용되는 것은 Hibernate입니다.
Java와 DB 데이터 간의 매핑을 자동화해주어서 개발자는 SQL 문을 작성할 필요가 없어지고, DB가 바뀌어도 DB에 따라 새로운 SQL을 작성할 필요가 없이 Hibernate에서 DB에 맞는 적합한 SQL 문을 생성해 줍니다.
JPA 특징
MyBatis와 다르게 SQL문의 작성이 불필요하며 ORM 내부적으로 java 메소드에 적합한 SQL문이 자동으로 생성이 되어 실행되게 됩니다. Java 개발자는 클래스만 만들어서 사용하고, ORM 프레임워크가 자동으로 관련된 SQL을 만들어 줍니다.
JPA의 장점, 단점
장점:
- 쿼리를 하나하나 작성할 필요가 없어 코드량이 줄어든다.
- 가독성이 좋다.
- 간편하게 수정이 가능하다. (유지보수, 리팩토링 용이)
- 동일한 쿼리에 대한 캐시 기능을 사용하기 때문에 더욱 높은 성능을 낼 수 있다.
단점:
- 매핑 설계를 잘못했을 때 성능 저하가 발생할 수 있다.
- JPA를 제대로 사용하려면 알아야할 것이 많아서 학습하는데 시간이 오래 걸린다.
- 다수의 테이블 조인시 신경써야 할게 많다.
MyBatis와 JPA 비교
1. 설정의 복잡성
MyBatis
SQL 매핑과 설정이 비교적 수동적이고 상세하다. 개발자가 SQL을 완전히 제어할 수 있게 하지만, 동시에 설정과 SQL 매핑을 위한 상당한 시간 투자를 요구한다.
JPA
매핑 작업을 위한 어노테이션과 ORM(Object-Relational Mapping)을 통해 더 높은 수준의 추상화를 제공한다.
이로 인해 초기 설정이 더 복잡해 보일 수 있지만, 일단 설정되고 나면 반복적인 CRUD 작업을 자동화할 수 있다.
2. 개발 생산성
MyBatis
개발자가 SQL을 직접 작성해야 하므로, 복잡한 쿼리를 자유롭게 다루고자 할 때 유용하다. 그러나 이것은 또한 개발자가 모든 SQL을 직접 관리해야 한다는 것을 의미한다.
JPA
CRUD 작업을 위한 표준화된 API를 제공하며, 복잡한 쿼리를 위해 JPQL(Java Persistence Query Language) 또는 Criterial API를 사용한다.
3. 데이터베이스 추상화 수준
MyBatis
데이터베이스 작업에 대한 세밀한 제어를 가능하게 하지만, 그만큼 데이터베이스의 구조에 밀접하게 의존한다.
JPA
데이터베이스와의 상호작용을 위해 더 높은 수준의 추상화를 제공하며, 이는 데이터베이스 간의 이식성을 높여준다.
개발자는 데이터베이스의 구체적인 세부사항보다는 객체 모델에 더 집중할 수 있다.
4. 성능 측면
MyBatis
직접 작성한 SQL에 의존하기 때문에, 성능 최적화가 상대적으로 쉽다.
JPA
동적인 쿼리 생성과 ORM의 복잡성으로 인해 성능 이슈가 발생할 수 있으나, 캐싱과 같은 JPA의 고급 기능을 통해 이를 보완할 수 있다.
5. 유지보수와 확장성
MyBatis
SQL이 분산되어 있기 때문에 변경 사항이 발생할 경우 관련된 모든 SQL을 찾아 수정해야 한다. 이는 유지보수를 어렵게 만들 수 있다.
JPA
ORM을 통해 객체 중심으로 데이터베이스를 관리하기 때문에 유지보수와 확장성이 좋다. 객체 모델의 변경이 데이터베이스에 자동으로 반영되기 때문에 코드의 일관성을 유지하기 쉽다.
결론
JPA와 MyBatis는 각각의 장점과 단점들을 가지고 있다. 그렇기 때문에 프로젝트의 목적과 상황에 따라 적절한 기술을 선택해야 한다.
Reference