
ORM 이란 객체와 관계형 데이터 베이스를 연결해주는 기술입니다.
Java로 개발 시, 데이터베이스를 연결해야 할 때 SQL 언어가 아닌 객체 지향 프로그래밍 언어(예: Java)로 RDBMS(관계형 데이터 베이스)를 조작할 수 있도록 도와주는 기술입니다.
즉, SQL 쿼리를 직접 작성하지 않아도 객체를 통해 데이터베이스에 접근, 저장, 수정, 삭제를 가능하게 해 ****줍니다.
대표적인 ORM 프레임워크로 Java에는 JPA(인터페이스), Hibernate(구현체), Python에는 Django ORM, C#에는 Entity Framework 가 존재합니다.
그러면 간단한 예시로 살펴봅시다.
@Entity
@Getter
@Setter
public class User {
@Id
private Long id;
private String name;
}
위와 같은 User 엔티티가 존재한다고 할 때, @Entity를 통해 JPA가 이 클래스를 테이블 처럼 다루게 해줍니다.
또한 @Id를 통해서 테이블에서 PK(Primary Key)로 지정해 줄 수 있습니다.
public class Main {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("EntityManager");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransacction();
tx.begin();
User user = new User();
user.setId(1L);
user.setName("호기심");
em.persist(user); // INSERT 쿼리 없이 객체 저장
tx.commit();
em.close();
emf.close();
}
}
위의 Main에서 em.persist()를 통해 SQL 문 없이 객체를 INSERT가 가능케 해 줍니다.
그렇다면 장점/단점에 대해서 간략히 봅시다
장점으로는…
단점도 존재하는데…
그렇다면 아까 전 Java에서 사용한다는 ORM 기술에 대해서 알아볼까요?
JPA (Java Persistence API)는 ORM 기술 표준으로 사용되는 인터페이스의 모음입니다.
즉, 실제로 구현된 것이 아닌 (인터페이스이기에) 구현된 클래스와 매핑을 위한 프레임워크입니다.
개발자는 JPA 인터페이스를 사용하고, 실제 동작은 구현체(Hibernate)가 담당하게 됩니다.
JDBC는 자바에서 데이터 베이스와 통신하기 위한 가장 기본적인 API입니다.
SQL 을 직접 작성하고, 커넥션과 리소스를 직접 관리해야 합니다.
public class Jdbc {
public static void main(String[] args) throws Exception {
// 1. DB 연결
Connection connection = DriverManager.getConnecction(
"jdbc:mysql://localhost:3306/mydb", "user", "password");
// 2. SQL 문
String sql = "INSERT INTO member (id, name) VALUES (?, ?)";
PreparedStatement prepared = connection.prepareStatement(sql);
prepared.setLong(1,1L);
prepared.setString(2, "홍길동");
// 3. SQL 실행
prepared.executeUpdate();
// 4. 자원 정리
prepared.close();
connection.close();
}
}
즉, 위의 예시에서 보면, 데이터 베이스 연결 → SQL 실행 → 리소스 해제 까지 코드로 작성해 코드의 가독성이 떨어집니다.
JPA를 사용하면,
SQL 작성이 직접 작성 → 대부분 자동으로 작성,
객체 매핑이 수동 → 어노테이션을 이용해 자동으로 매핑,
리소스 관리가 직접 → 대부분 프레임워크가 자동으로 처리,
트렌젝션 관리를 직접 → EntityManager로 관리
성능 튜닝을 수동 → 자동 캐싱, 지연 로딩 등 가능케 해 줍니다.
이런 점들을 추상화해 사용하게 해 줍니다.
@Entity
public class Member {
@Id
private Long id;
private String name;
public Member(Long id, String name) {
this.id = id;
this.name = name;
}
}
위 코드로 클래스 선언으로 직접 테이블을 설계 및 매핑 해줍니다.
여기서 EntityManager을 직접 사용할 수 있지만,
이를 더 간단하게 만들어주는 것이 Spring Data JPA의 JpaRepository입니다.
Spring Data JPA가 제공하는 인터페이스로, 내부적으로 JPA의 EntityManager를 사용하지만, 개발자가 직접 작성할 필요가 없다는 것이 큰 장점입니다. 또한 CRUD, 페이징, 정렬 등 공통 기능을 제공합니다.
public interface MemberRepository extends JpaRepository<Member, Long> {
// 추가 메서드 없이 save, findById, delete 등의 기본 기능을 사용 가능합니다.
}
위를 통해 코드를 줄여주고 반복적인 코드를 줄여 핵심 비즈니스 로직 개발에만 집중 가능하게 해 줍니다.
아래는 사용 예시입니다.
public void saveMember() {
Member member = new Member(1L, "홍길동);
memberRepository.save(member); // INSERT 쿼리 자동 수행
}
그 외에도 @Query 를 통해 커스터마이징도 가능합니다!
JPA 가 동작할 수 있는 이유는 EntityManager 과 영속성 컨텍스트(Persistence Context) 덕분이다.
영속성 컨텍스트를 관리하고 엔티티를 DB에 저장하거나 조회할 수 있는 핵심 API이다.
JPA 의 동작은 Entity를 기준으로 돌아가는데, 이 때 Entity를 관리하는 것이 EntityManager이다.
EntityManager의 역할로는 다음과 같다.
getTransaction().begin(), commit() 을 수행한다.요청이 오면 EntityManager가 만들어지게 되고, Entity들을 영속성 컨텍스트에 생성해 Entity 를 영속화한다.
EntityManager가 영속성 컨텍스트를 기반으로 요청을 처리한다.
(Entity를 영속화 한다는 의미는 JPA 가 관리하는 영속성 컨텍스트에 등록한다 는 의미이다.)
생명주기는 4단계가 존재한다.
new 로 만든 상태로, 영속성 컨텍스트에 포함되지 않는다.(DB와 관련이 없다.)
em.persist(member) 호출 후, 영속성 컨텍스트에 등록된 상태이다.
JPA 가 해당 객체를 추적한다. (1차 캐시에 저장, 변경 감지 적용, 커밋 시 DB에 반영)
영속 상태였던 객체가 더 이상 영속성 컨텍스트에 의해 관리되지 않는 상태이다.
em.close() 등을 토해 발생하며, 아직 객체가 존재하지만, JPA가 추적하지 않는 상태이다.
DB에서 삭제 예약 상태이며, 트랜잭션 커밋 시 DELETE 쿼리가 실행된다.

EntityManager 은 우리가 직접 만드는 것이 아닌, JpaRepository로 확장 시 EntityManager 를 자동으로 주입받아 사용합니다. 따라서 이에 대해 신경을 쓰지 않아도 됩니다.
쉽게 말하면, JPA가 관리하는 엔티티 객체들이 저장되어 있는 1차 캐시(메모리 상의 공간) 이다.
자바 객체와 DB 테이블 사이의 동기화를 관리하는 핵심 장소로, EntityManager가 내부적으로 영속성 컨텍스트를 생성하고 조작한다.
메모리 안에 있는 일종의 엔티티 저장소로 생각하면 편하다. EntityManager가 생성되면 그 안에 자동으로 하나가 생성되어 여기 들어간 엔티티만 JPA가 변경 감지, 동일성 보장, 쓰기 지연 등의 기능을 수행해 준다.
JPA는 DB에 바로 INSERT/UPDATE 하는 것이 아닌, 영속성 컨텍스트에 넣고 커밋 시점에 이를 확인해 필요한 SQL만 실행합니다.
위의 기능은 영속성 컨텍스트 안에 있을 때만 작동합니다.
영속성 컨텍스트는 트랜젝션 단위로 관리하는 것이 일반적이기에, Spring에서는 @Transactional 범위가 곧 영속성 컨텍스트의 생명 범위가 됩니다.