- 상속
- DB에는 상속 관계가 없음
- 각각의 객체별로 데이터를 저장해야하고, JOIN을 사용해서 데이터를 조회해야 함
- 데이터를 저장하고 조회하기 까다롭기 때문에 DB에 저장할 객체는 상속 관계를 사용하지 않음
- 연관관계
- DB는 외래키를 사용하여 표현
- 객체는 참조를 사용하여 표현
// 데이터베이스 중심 객체 설계 public class Tutor { private Long id; // PK private Long companyId; // FK private String name; } public class Company { private Long id; // PK private String name; }
// 객체 중심 설계 public class Tutor { private Long id; // PK private Company company; // 참조 연관관계 private String name; public Company getCompany() { return company; } public Company setCompany(Company company) { this.company = company; } } public Company { private Long id; // PK private String name; }
SELECT p.*, c.* FROM product p JOIN category c ON p.category_id = c.id;
product.getCategory(); // 가능 product.getOrder(); // 불가능
- 객체 그래프
- 객체는 연관된 객체를 탐색할 수 있어야 하지만, 실행된 SQL만큼만 탐색 가능해짐
- Entity의 신뢰성에 문제 발생
- 연관 객체를 한꺼번에 조회하면 신뢰성은 생기지만,
- SQL 쿼리가 무거워짐
- 진정한 의미의 계층 분할이 어려움
- 필요 없는 데이터도 항상 함께 조회
Product product1 = productRepository.findById(productId); Product product2 = productRepository.findById(productId); product1 == product2; // false
- 객체의 비교
- 데이터는 같지만, 새로운 인스턴스이기 때문에 주소값이 다름
- Collection에 저장하면 문제를 해결할 수 있음
객체 지향 프로그래밍 언어인 Java와 관계형 데이터베이스 간의 패러다임 불일치 문제를 해결하여 데이터베이스 작업을 객체 지향적으로 수행할 수 있도록 지원. 대표적으로 Hibernate를 사용.
- 객체와 관계형 DB를 자동으로 매핑하여 패러다임 불일치 문제를 해결
- 개발자 대신 데이터베이스와 상호작용하는 역할을 수행
- 생산성
- 유지보수성
- 패러다임 불일치 문제 해결
- SQL 중심적인 개발에서 객체 중심으로 개발하기 때문에
- 성능 향상
- 1차 캐시
- 쓰기 지연
- 지연 로딩
- 즉시 로딩
Entity 객체를 영속성 상태로 관리하는 일종의 캐시 역할을 하는 공간으로 여기에 저장된 Entity는 데이터베이스와 자동으로 동기화되며, 같은 트랜잭션 내에서는 동일한 객체가 유지됨.
- 데이터베이스에서 엔티티란 저장할 수 있는 데이터의 집합을 의미
- JPA에서 엔티티란 데이터베이스의 테이블을 나타내는 클래스를 의미
- 비영속(new/transient)
- 영속성 컨텍스트가 모르는 새로운 상태
- 데이터베이스와 전혀 연관이 없는 객체
- 영속(managed)
- 영속성 컨텍스트에 저장되고 관리되고 있는 상태
- 데이터베이스와 동기화되는 상태
- 준영속(detached)
- 영속성 컨텍스트에 저장되었다가 분리되어 더 이상 기억하지 않는 상태
- 영속성 컨텍스트가 제공하는 기능을 사용하지 못함
- 삭제(removed)
- 영속성 컨텍스트에 의해 삭제로 표시된 상태
- 트랜잭션이 끝나면 데이터베이스에서 제거
- 엔티티를 영속성 컨텍스트에 저장할 때 생성되는 메모리 내 캐시
- 엔티티는 1차 캐시에 먼저 저장
- 이후 같은 엔티티를 요청하면 DB를 조회하지 않음
- 1차 캐시에서 데이터를 반환하여 성능을 높임
- 동일한 트랜잭션 안에서만 사용 가능
- 트랜잭션이 종료되면 영속성 컨텍스트는 삭제됨
- 새로운 엔티티를 영속시키면 1차 캐시에 저장됨
- id가 1번인 엔티티를 조회하면, DB가 아닌 1차 캐시에서 데이터를 반환함
- id가 2번인 엔티티를 조회하면, 1차 캐시에 해당 데이터가 없으므로
- DB를 조회하고, 1차 캐시에 저장한 후 데이터를 반환함
- 동일한 트랜잭션 안에서 특정 엔티티를 여러 번 조회해도 항상 같은 객체 인스턴스를 반환
- 1차 캐시를 사용하여 동일한 객체를 참조하게 하기 때문에 일관성 유지 가능
- 동일한 트랜잭션 내에서 생성된 SQL들을 Commit 시점에 한꺼번에 반영
- 영속성 컨텍스트가 엔티티의 초기 상태를 저장하고 커밋 시점에 현재 상태와 비교하여 변경 사항이 있는지 확인하는 기능
- DB에서 조회한 데이터에 대해 스냅샷(snapshot) 저장
- 커밋 시점에 엔티티와 스냅샷을 비교
- 변경 사항이 있다면 UPDATE 쿼리문을 생성하여 반영
- 영속성 컨텍스트의 변경 내용을 데이터베이스에 반영하는 기능
- 변경된 엔티티 정보를 SQL로 변환해 데이터베이스에 동기화함
- 트랜잭션 커밋 시 자동으로 실행되지만, 특정 시점에 데이터베이스 반영이 필요하다면 수동으로 호출도 가능