김영한 님의 JPA 강좌를 들으면서 작성한 글입니다.
강좌 보기글에 대한 피드백 환영합니다.
상속
객체는 상속관계가 있지만, 관계형 데이터베이스는 상속 관계가 없다.
연관관계
객체는 reference(참조)를 가지고 있다. (예를들어, 연관된 객체를 getter로 가져올 수 있음)
관계형 데이터베이스는 PK(Primary Key)나 FK(Foreign Key)로 join을 해서 필요한 데이터를 찾을 수 있다.
데이터 타입
데이터 식별 방법
ORM
- Object-relational mapping(객체 관계 매핑)
- 객체는 객체대로 설계
- 관계형 데이터베이스는 관계형 데이터베이스대로 설계
- ORM 프레임워크가 중간에서 매핑
- 대중적인 언어에서 대부분 ORM 기술이 존재
JAVA 애플리케이션에서 JPA에게 명령하면, JPA는 JDBC API를 사용해서 SQL을 만들어서 DB에 보낸다.
- SQL 중심적인 개발에서 객체 중심으로 개발
- 생산성
- 유지보수
- 패러다임의 불일치 해결
- 성능
- 데이터 접근 추상화와 벤더 독립성
- 표준
CRUD가 다 정의되어 있어서 편하다.
기존에는 필드 변경시 모든 SQL을 수정했어야 했다.
(예를들어, 필드 한 개가 추가되면 그것을 사용하는 모든 곳을 변경해야 한다)
JPA를 사용하면 필드만 추가하면 된다. (db에 column이 추가되었다는 가정 하에)
jpa.persist(album);
을 명령하면 JPA가 알아서 처리해준다.
JPA는 persist 명령을 받고, ITEM table, ALBUM table 두 군데 모두 INSERT 쿼리를 날린다.
jpa.find(Album.class, albumId);
라는 명령을 하면 JPA가 알아서 처리해준다.
JPA는 Item과 Album을 join해서 찾아옴.
연관관계 저장
member.setTeam(team);
jpa.persist(member);
객체 그래프 탐색
Member member = jpa.find(Member.class, memberId);
Team team = member.getTeam();
연관 관계를 저장하고, 가져올 때는 마치 java collection에 넣었던 것처럼 꺼내올 수 있다.
String memberId = "100";
Member member1 = jpa.find(Member.class, memberId);
Member member2 = jpa.find(Member.class, memberId);
member1 == member2; // 같다
동일한 트랜잭션에서 조회한 엔티티는 같음을 보장!
(1차 캐시를 사용하기 때문)
String memberId = "100";
Member m1 = jpa.find(Member.class, memberId);
Member m2 = jpa.find(Member.class, memberId);
println(m1 == m2); // true
위의 코드에서 SQL 1번만 실행한다!
transaction.begin(); // [트랜잭션] 시작
em.persist(memberA);
em.persist(memberB);
em.persist(memberC);
//여기까지 INSERT SQL을 데이터베이스에 보내지 않는다.
//커밋하는 순간 데이터베이스에 INSERT SQL을 모아서 보낸다.
transaction.commit(); // [트랜잭션] 커밋
지연 로딩은 member를 조회 했을 때, member만 가져온다.
그리고 3번째 줄에서 team.getName을 했을 때, jpa가 db에 team에 대한 query를 날려서 가져온다.
즉,필요한 시점에 쿼리를 날려 값을 가져온다.
즉시 로딩은 member를 조회 했을 때, member와 연관된 객체까지 모두 가져온다.
따라서 member를 가져왔을 때 member만 쓴다고 하면 지연 로딩이 좋고,
member를 가져왔을 때 member와 연관 객체를 같이 쓰는 경우엔 즉시 로딩이 좋다.
정리 깔끔해서 이해가 잘되네요 감사합니다!