요즘은 NoSQL도 많이 사용한다지만 아직 가장 보편적인 데이터베이스는 RDB(Relational Database)이다.
객체지향 프로그래밍을 하면서 생성한 도메인 객체들은 관계형 데이터베이스에 저장되어서 관리된다.
즉, 도메인 클래스가 DB의 테이블과 대응되고 해당 클래스의 객체는 테이블의 엔티티로서 저장되는 것이다.
이를 위해서는 RDB 테이블에 해당 객체를 매핑(Mapping)시켜줘야 한다.
이를 ORM(Object Relational Mapping)이라고 한다.
고대(?) 자바 개발에서는 이 모든 작업을 JDBC를 통해 처리했다.
그런데 이 방법은 드라이버를 연결하고 SQL을 문자열로 하나하나 직접 작성하는 기계적이고 반복적인 작업에 소요되는 시간이 너무나 컸다.
너무나도 불필요한 낭비였지만 다른 대안이 없었기에 불가피했다.
또한 아무리 객체를 RDB에 매핑하여 저장한다지만 이 둘이 상속, 연관관계, 데이터 타입, 데이터 식별 방법 등 본질적인 패러다임까지 완전히 같은 것은 아니기에 여러 가지 문제들이 발생했다.
이런 배경 속에 등장한 것이 JPA(Java Persistence API)이다.
JPA는 객체를 마치 자바 Collections에 저장해 관리하는 것처럼 편리하게 DB에 저장할 수 있도록 해주는 ORM 프레임워크이다.
RDB는 RDB대로 그 특성에 맞게 설계하고 객체는 객체대로 설계한다. 사용자는 편하게 객체를 저장하고 귀찮은 매핑 작업은 전부 JPA가 처리한다.
즉, 패러다임의 불일치에 대해서 신경쓰지 않고 작업하는 것이다.
하지만 내부적으로는 여전히 JDBC가 사용된다. 사용자가 직접 사용하진 않게 되었지만 사용자 편하게 내린 명령을 JPA가 이전까지 해왔던 JDBC를 사용한 그런 복잡한 과정들을(SQL을 하나하나 작성하는 등) 거쳐 RDB에 매핑해주는 것이다.
기본적인 CRUD 기능에 대한 쿼리는 내부적으로 JPA가 전부 알아서 짜주기 때문에 더 이상 기계적, 반복적인 SQL 작업에 오랜 시간 고통받을 필요가 없어졌다.
JPA는 인터페이스의 모음이고 그것을 상속한 클래스가 여러 가지 존재하지만 hibernate가 대표적으로 사욯된다.
아래와 같은 방식으로 가장 기본적인 CRUD 기능을 쿼리 작성 없이 간단하게 사용할 수 있다.
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
Member member = new Member();
member.setId(1L);
member.setName("name1");
// Create
em.persist(member); // list.add(Object o) 처럼 간편하게 DB에 객체 저장
// Read
Member findMember = em.find(Member.class, 1L); // PK를 사용하여 간편하게 읽어옴
// Update
findMember.setName("change name"); // 조회한 객체에 대하여 수정을 하는 것만으로 update쿼리까지 완료됨
// Delete
em.remove(member); // 조회한 객체를 삭제하면 테이블에서도 해당 엔티티 바로 삭제됨
tx.commit();
그런데, 위의 CRUD는 모두 하나의 객체에 대한 작업이다.
그럼 특정 조건의 엔티티 여러 개를 조회해야 하는 등 더 복잡한 경우엔 어떻게 할까?
이것을 위한 JPQL을 이 다음 글에서 설명한다.
'김영한님 스프링 강의 정리 > JPA' 카테고리의 다른 글
연관관계 매핑과 관계의 주인 (0) | 2021.02.21 |
---|---|
기본 키 매핑 전략 - IDENTITY, SEQUENCE (0) | 2021.02.21 |
Flush에 대해 (0) | 2021.02.19 |
Persistence Context 에 대해 (0) | 2021.02.19 |
JPQL이란? (0) | 2021.02.19 |