개발자 취업준비/springboot

ORM이란? JPA와 myBatis 차이

naspeciallist 2025. 2. 4. 21:25


이 글은 스프링부트3 백엔드 개발자 되기 책을 바탕으로 공부한 내용을 정리한 게시글 입니다.

 

 

1. ORM이란?


ORM(object-relational mapping)은 자바의 객체와 데이터베이스를 연결하는 프로그래밍 기법입니다. 자바에서 데이터베이스에 있는 값을 가져올려면 보통 SQL이라는 언어로 데이터를 꺼내 사용합니다. 하지만 ORM이 있다면 데이터베이스의 값을 마치 객체처럼 사용 할 수 있습니다. 쉽게 말하자면 ORM을 통해서 SQL을 전혀 몰라도 데이터베이스에 접근하여 원하는 데이터를 받아 올 수 있습니다. 즉 객체와 데이터베이스를 연결해 자바 언어로만 데이터베이스를 다룰 수 있게 하는 도구를 ORM이라고 합니다. ORM은 다음과 같은 장점과 단점이 있습니다.

 

 

  • 장점
    • SQL을 직접 작성하지 않고 사용하는 언어로 데이터베이스에 접근할 수 있습니다.
    • 객체지향적으로 코드를 작성 할 수 있기 떄문에 비즈니스 로직에만 집중할 수 있습니다.
    • 데이터베이스 시스템이 추상화되어 있기 때문에 MySQL에서 PostgreSQL로 전환하다고 해도 추가로 드는 작업이 거의 없습니다. 즉 데이터베이스 시스템에 대한 종속성이 줄어듭니다.
    • 매핑하는 정보가 명확하기 때문에 ERD에 대한 의존도를 낮출 수 있고 유지보수 할 때 유리합니다.
  • 단점
    • 프로젝트의 복잡성이 커질수록 사용 난이도도 올라갑니다.
    • 복잡하고 무거운 쿼리는 ORM으로 해결이 불가능한 경우가 있습니다.

 

2. JPA와 하이버네이트


 

DBMS에도 여러종류가 있는 것처럼 ORM에도 여러 종류가 있습니다. 자바에서는 JPA(java persistence API)를 표준으로 사용합니다. JPA는 자바에서 관계형 데이터베이스를 사용하는 방식을 정의한 인터페이스입니다. 인터페이스이므로 실제 사용을 위해서는 ORM프레임워크를 추가로 선택해야 합니다. 대표적으로는 하이버네이트(hibernate)를 많이 사용합니다. 하이버네이트는 JPA 인터페이스를 구현한 구현체이자 자바용 ORM 프레임워크입니다. 내부적으로 JDBC API를 사용합니다. 하이버네이트의 목표는 자바 객체를 통해 데이터베이스 종류에 상관없이 데이터베이스를 자유자제로 사용 할 수 있게 하는데 있습니다.

3. MyBatis란?


MyBatis는 SQL 기반의 데이터 접근을 보다 쉽게 관리할 수 있도록 도와주는 데이터 매퍼 프레임워크입니다. JPA 및 하이버네이트처럼 ORM을 제공하는 것이 아니라, SQL 문을 직접 작성하여 실행할 수 있도록 지원하는 방식입니다.

 

myBatis는 다음과 같은 특징이 있습니다.

 

  • SQL을 직접 작성 가능: MyBatis는 SQL을 직접 작성할 수 있어, 복잡한 쿼리를 보다 세밀하게 조정할 수 있습니다.
  • 객체와 SQL 매핑 지원: XML 혹은 애노테이션을 사용하여 객체와 SQL 쿼리를 매핑할 수 있습니다.
  • 유연한 쿼리 처리: JPA처럼 자동 매핑을 지원하는 것이 아니라, 개발자가 원하는 SQL을 직접 작성하여 최적화할 수 있습니다.
  • 동적 SQL 지원: 조건문을 활용하여 동적으로 SQL을 생성할 수 있으며, XML 기반으로 관리할 수 있습니다.

우리나라는 안정성과 속도를 중요시하기 때문에 쿼리를 직접 작성하는 Mybatis을 더 선호합니다. 
그래도 MyBatis 대신 Hibernate에 능숙해진다면 생산성을 상당히 높힐 수 있습니다.
하지만 JPA를 사용하면 통계나 동적 쿼리 같은 복잡한 쿼리를 처리하는 것이 어렵고 복잡합니다. 그래서 QueryDSL을 함께 이용하여 복잡한 로직을 처리 할 수 있습니다.
MyBatis와 Hibernate 모두 각각의 특징을 갖고 있기 때문에 상황에 맞는 적합한 ORM을 사용하는 것이 중요합니다.

현업에서의 프로젝트에서는 MyBatis와 JPA를 적절한 상황에 맞춰 섞어쓰는 추세라고 합니다. 

 

4. ORM 활용 예제


 

 1. ORM을 사용하지 않은 코드(JDBC 사용)

public class JdbcExample {
    public static void main(String[] args) {
        String url = "jdbc:mysql://localhost:3306/mydb";
        String username = "root";
        String password = "password";

        try (Connection conn = DriverManager.getConnection(url, username, password)) {
            String sql = "SELECT * FROM users WHERE id = ?";
            PreparedStatement pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1, 1);
            ResultSet rs = pstmt.executeQuery();

            while (rs.next()) {
                System.out.println("User ID: " + rs.getInt("id"));
                System.out.println("User Name: " + rs.getString("name"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 

 

orm을 사용하지 않고 JDBC를 이용하여 SQL을 작성하고 실행하는 방식입니다.

이 방법은 SQL을 직접 작성해야 하며, 데이터베이스 연결, 쿼리 실행, 매핑을 수동으로 처리해야 합니다.

코드가 길고 유지보수가 어렵다는 단점이 있습니다. 또한 가독성이 떨어져서 작업이 불편해집니다.

 

2.MyBatis를 이용한 코드

 

myBatis는 오픈소스 라이브러리 입니다. MyBatis는 자주사용되는 라이브러리이기 때문에 spring-data-mybatis라는 프로젝트를 통해 스프링에서 더 편리하게 이용할 수 있습니다. myBatis는 기본적으로 Database처리를 위한 Mapper 인터페이스와 Mapper.xml파일을 사용합니다. Repository에서 메서드의 이름은 queryId에 매핑되며 xml파일에서 해당쿼리의 id를 기준으로 쿼리를 실행합니다.

 

Mapper 인터페이스

@Mapper
public interface UserMapper {
    @Select("SELECT * FROM users WHERE id = #{id}")
    User findUserById(int id);
}

 

 

XML 기반 SQL 매핑

<mapper namespace="com.example.mapper.UserMapper">
    <select id="findUserById" parameterType="int" resultType="com.example.model.User">
        SELECT * FROM users WHERE id = #{id}
    </select>
</mapper>

 

서비스에서 사용

@Service
public class UserService {
    private final UserMapper userMapper;

    public UserService(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    public User getUserById(int id) {
        return userMapper.findUserById(id);
    }
}

 

 

  • SQL을 직접 제어할 수 있어 최적화가 용이합니다.
  • XML 또는 애노테이션을 활용하여 SQL을 관리할 수 있습니다.

 

3. JPA를 사용한 코드

JPA를 사용하면 SQL을 작성하지 않고도 데이터베이스와 객체를 매핑할 수 있습니다. 또한 JPA도 myBatis와 마찬가지로 스프링에서 좀 더 편리하게 사용하기 위해서 spring-data-jpa를 제공합니다.

JPA는 Java 객체와 테이블을 매핑시키는 ORM 기술이므로 Java 클래스에 매핑 정보를 넣어주어야 합니다.

Entity 클래스

@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

}

 

 

Repository 인터페이스

public interface UserRepository extends JpaRepository<User, Long> {
}

 

서비스에서 사용

@Service
public class UserService {
    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public User getUserById(Long id) {
        return userRepository.findById(id).orElse(null);
    }
}

 

 

  • SQL을 직접 작성하지 않아도 됩니다.
  • JPA의 영속성 컨텍스트를 활용하여 데이터 변경을 자동으로 감지할 수 있습니다.
  • 유지보수가 쉬우며 객체 중심의 개발이 가능합니다.

 

4. 정리


기존에는 JDBC를 이용하여 sql문을 직접 입력하여 데이터베이스에 접근 할 수 있었습니다. 하지만 JDBC를 사용하면 데이터베이스 연결, 쿼리 실행, 매핑을 수동으로 처리해야 하며 코드가 너무 길고 복잡하며 많은 쿼리를 다루기도 어렵고 코드 수정 또한 어려워 유지보수가 어렵다는 단점이 있습니다. 이러한 불편함을 해결하기 위해 myBatis라는 오픈소스 라이브러리가 만들어졌습니다. myBatis를 이용하면 XML을 통해 SQL구문을 관리 할 수 있기 때문에 코드가 더 간결해졌으며 코드 수정이 더 용이해져 유지보수성이 높아졌습니다. 또한 SQL을 직접 제어하기 때문에 프로젝트의 안정성과 속도를 최적의 상태로 개선 할 수 있다는 장점 때문에 우리나라에서 많이 이용하는 방법입니다.하지만 이제는 쿼리를 직접 작성하지 않고, 데이터베이스의 정보를 객체 형식으로 다룰 수 있도록 해주는 ORM기술이 등장하였습니다. ORM을 사용하면 데이터베이스와 객체 간의 매핑이 자동으로 이루어지기 때문에, 보다 직관적인 코드 작성이 가능하며 개발 생산성이 크게 향상됩니다.

그중에서도 JPA(Java Persistence API) 는 자바에서 ORM을 표준화한 기술로, 객체 중심적인 데이터 접근을 가능하게 합니다. JPA를 사용하면 SQL을 직접 작성할 필요 없이 엔티티 객체를 통해 데이터베이스를 다룰 수 있으며, 특정 데이터베이스에 종속되지 않습니다. MySQL, PostgreSQL, Oracle 등 다양한 DBMS에서 동일한 코드로 동작합니다.

 

또한 SQL문을 이용하지 않고 객체중심적인 방식으로 데이터를 처리 할 수 있습니다. 비즈니스 로직에 집중 할 수 있으며 데이터베이스 변경에도 최소한의 수정만 필요하기 떄문에 생산성이 크게 향상됩니다.

 

테이블 구조가 변경되더라도 객체의 필드만 수정하면 되므로 유지보수가 훨씬 쉬워집니다. SQL문을 일일히 수정할 필요가 없고 엔티티 클래스와 관계 설정만으로 데이터 접근이 가능하기 때문에 유지보수성이 크게 향상됩니다.

 

JPA는 영속성 컨텍스트(Persistence Context) 를 통해 엔티티의 상태를 자동으로 관리하며, 변경 감지(Dirty Checking), 지연 로딩(Lazy Loading) 등 강력한 기능을 제공합니다.
이를 통해 개발자가 명시적으로 update 쿼리를 작성하지 않아도, 변경된 내용이 자동으로 반영됩니다.

 

SQL과 유사한 JPQL을 제공하여 객체를 대상으로 한 쿼리를 사용할 수 있습니다.
특정 DBMS에 종속되지 않으며, 객체 중심적인 접근 방식으로 데이터를 다룰 수 있습니다.

 

JPA와 myBatis의 이러한 장점들 떄문에 요즘에는 JPA를 기본으로 사용하고, 복잡한 SQL이 필요한 경우 MyBatis를 활용하는 추세입니다.