JPA TIL #1

원종운·2021년 1월 7일
1

SQL을 직접 다루는 경우의 문제점

1. 반복적인 작업

  • CRUD 기능을 위한 비슷한 패턴의 많은 SQL과 JDBC API 코드 작성을 해야한다는 문제가 발생합니다.

2. SQL에 의존적인 개발

  • 객체의 필드가 하나 추가될 경우 매번 모든 CRUD 기능을 수행하는 SQL을 수정해주어야하는 문제가 발생합니다. 오타가 발생하는 등 이슈가 빈번하게 발생되는 이유 중 하나입니다.

  • 엔티티가 참조 필드를 가지고 있을 경우 참조 필드에 접근할 수 있는지 여부, 즉 연관 엔티티 조회 여부는 해당 엔티티와 관련된 SQL문을 확인하여야하므로 엔티티 자체를 신뢰할 수 없다는 문제가 발생합니다.

  • 위와 같은 문제로 계층(Layer) 분할이 어렵다는 문제가 발생합니다.

JPA로 문제 해결

  • JPA가 제공하는 API를 사용함으로서 SQL을 직접 작성하지 않고, JPA에게 SQL 생성을 위임을 할 수 있습니다.

JPA CRUD

  • Member 엔티티, JPA(EntityManager) 등 기타 코드는 생략...

1. 저장

jpa.persist(member);
  • 저장하고자 하는 엔티티를 분석하여 INSERT SQL을 JPA가 생성하여 데이터베이스에 전달하여 저장하여줍니다.

2. 조회

Member member = jpa.find(Member.class, memberId);
  • Primary Key가 memberId를 찾는 SELECT SQL을 JPA가 생성하여 데이터베이스에 전달한 후, 그 결과를 반환받아 Member 엔티티 형식에 맞게 엔티티를 생성하여 반환하여줍니다.
  • 조회하여 JPA가 반환해준 엔티티는 JPA가 관리하는 영속적인 엔티티입니다.

3. 수정

Member member = jpa.find(Member.class, memberId);
member.setAge(20);
  • 별도의 JPA가 update 메소드를 지원하지 않습니다.
  • 영속적인 엔티티는 스냅샷의 형태로 엔티티의 초기의 값을 보관하고 있다가 엔티티의 필드들이 변경될 경우 그것을 감지하여 자동으로 UPDATE SQL을 JPA가 생성하여 데이터베이스에 전달하여 수정하여줍니다.
  • 주의하여야할 점은 JPA가 관리하는 영속적인 엔티티에 대해서만 적용됩니다. 자세한 것은 다음에 포스팅 하도록 하겠습니다.

4. 삭제

jpa.remove(member);
  • 해당 엔티디의 Primary Key를 기준으로 DELETE SQL을 JPA가 생성하여 데이터베이스에 전달하여, 삭제하여줍니다.
  • 삭제된 엔티티는 영속적인 엔티티에서 비영속적인 엔티티로 변경되어 JPA의 관리를 받지 않습니다.

5. 연관객체 조회

Member member = jpa.find(Member.class, memberId);
Team team = member.getTeam();
  • Member 엔티티와 연관된 객체인 Team 객체를 자유롭게 조회할 수 있습니다.
  • 실제로는 쓰기 지연(lazy loading)이 적용되어, getTeam()으로 얻은 Team 엔티티에 대한 참조는 프록시(가짜)이며, JPA가 SELECT SQL를 생성하여 데이터베이스에 전달하지 않습니다.
  • 실제로 해당 Team 엔티티인 team 객체를 사용할 때 SELECT SQL을 JPA가 데이터베이스에 전달하여, 그 결과를 반환받아 객체(엔티티)를 완성합니다.

참고서적 : 자바 ORM 표준 JPA 프로그래밍, 김영한, 에이콘출판사

해당 서적을 읽고 내용을 정리하여 작성하는 글이나, 혹시 저작권등의 문제가 있을 경우 연락을 주시면 바로 내리도록 하겠습니다

profile
Java, Python, JavaScript Lover

0개의 댓글