스프링 데이터 JPA?
- 스프링 프레임워크에서 JPA를 편하게 사용할 수 있도록 지원하는 프로젝트
- 데이터 접근 계층(repository)를 인터페이스만 작성해도 런타임 시에 스프링 데이터 JPA가 구현 객체를 주입해줌
- 즉, 구현 클래스를 직접 작성하지 않고 인터페이스만 작성해도 CRUD를 할 수 있음
Continue reading
JPQL 조인
- 내부 조인 (INNERT JOIN)
String teamName = "teamA";
String query = "SELECT m FROM Member m INNER JOIN m.team t "
+ "WHERE t.name = :teamName";
List<Member> members = em.createQuery(query, Member.class)
.setParameter("teamName", teamName)
.getResultList();
- JPQL은 조인을 할때도 연관관계 필드를 사용함
String SQL = "SELECT M.ID, M.AGE ... FROM MEMBER M
INNER JOIN TEAM T ON M.TEAM_ID = T.TEAM_ID
WHERE T.NAME = ?
"
String JPQL = "select m FROM Member m INNER JOIN m.team t
WHERE t.name = ?"
Continue reading
JPQL
- JPQL은 객체지향 쿼리 언어
- JPQL은 SQL을 추상화해서 특정 데이터베이스에 의존하지 않음
- JPQL은 결국 SQL로 변환됨
Continue reading
1. 객체지향 쿼리
- JPA에서 엔티티를 조회하는 방법?
- EntityManager.find() 메소드
- 조건부 탐색을 하고싶을 땐? (e.g. 나이가 18세 이상인 회원을 조회)
- 모든 엔티티를 조회 후에 조건을 적용해야 함
- 데이터베이스 조회 시 필요한 내용을 최대한 거를 필요가 있음
- JPQL(Java Persistence Query Language)
- 테이블이 아닌 객체를 대상으로 검색하는 객체지향 쿼리
- SQL을 추상화 해서 특정 데이터베이스 SQL에 의존하지 않음
Continue reading
JPA의 데이터 타입
- 엔티티 타입
- 값 타입
- 기본값 타입(basic value type)
- 임베디드 타입(embedded type, 복합 값 타입)
- 컬렉션 값 타입(collection value type)
Continue reading
프록시란?
- JPA의 지연 로딩 기능을 사용하려면 실제 엔티티 객체 대신에 데이터베이스 조회를 지연할 수 있는 가짜 객체가 필요한데, 이것을 프록시 객체라고 함
- JPA의 지연 로딩 : 엔티티가 실제 사용될 때까지 데이터베이스 조회를 지연시키는 방법(실제 데이터를 사용할 때 조회)
- JPA의 표준 명세는 지연 로딩의 구현 방법을 JPA 구현체에 위임함
- 하이버네이트 기준으로 아래 내용 작성
- 하이버네이트가 지연 로딩을 지원하는 방법
- 프록시
- 바이트코드 수정 : 복잡해서 다루지 않음
Continue reading
고급 매핑
- 상속 관계 매핑
- 객체의 상속 관계를 데이터베이스에 어떻게 매핑하는지
- @MappedSuperclass
- 등록일, 수정일 같이 여러 엔티티에서 공통으로 사용하는 매핑 정보만 상속받고 싶을 때 사용
- 복합 키와 식별 관계 매핑
- 데이터베이스의 식별자가 하나 이상일 때 매핑하는 방법
- 데이터베이스 설계에서 이야기하는 식별, 비식별 관계에 대해서
- 조인 테이블
- 테이블을 외래키 하나로 연관관계 맺는 것이 아닌 연결 테이블을 이용해서 매핑하는 방법
- 엔티티 하나에 여러 테이블 매핑하기
Continue reading
다대일 단방향 [N:1]
- 가장 많이 사용되는 연관관계
- 회원은 Member.team 팀 엔티티 참조가 가능하지만 팀은 회원을 참조하는 필드가 없음. 따라서 단방향 연관관계
- ```java // 회원 엔티티 @Entity public class Member { @Id @GeneratedValue @Column(name = “MEMBER_ID”) private Long id;
Continue reading
객체는 참조를 통해서 다른 객체들과 연관관계를 맺고, 테이블은 외래키를 이용해서 다른 테이블과 연관관계를 맺는다.
Continue reading
JPA에서 지원하는 매핑 어노테이션은 다음과 같이 크게 4가지로 분류할 수 있음
- 객체와 테이블 매핑 : @Entity, @Table
- 기본 키 매핑 : @Id
- 필드와 컬럼 매핑 : @Column
- 연관관계 매핑 : @ManyToOne, @JoinColumn
Continue reading
1. 엔티티 매니저 팩토리와 엔티티 매니저
- 엔티티 매니저 팩토리
persistence.xml
로부터 데이터베이스 정보를 읽어와 엔티티 매니저 팩토리가 생성됨- 비용이 많이 들지만 여러 스레드가 동시에 접근해도 안전하기 때문에 한번만 생성하고 공유해서 사용해야 함
- 하이버네이트를 포함한 대부분의 구현체가 엔티티 매니저 팩토리가 생성될 때 DB의 커넥션 풀도 같이 생성해줌
- 엔티티 매니저
- 테이블 접근이 필요할 때마다 엔티티 매니저를 생성해서 테이블에 접근, 비용이 거의 들지 않음
- 동시성 문제가 있어 스레드 간에 공유하면 안됨
- 데이터베이스 연결이 필요한 시점에 커넥션을 획득함(EntityManager2)
- 연결이 필요한 시점? -> 트랜잭션을 시작할 때
Continue reading
1. 객체 매핑 시작
- 클래스와 테이블을 매핑하기 위해 어노테이션을 사용함
- ```java import javax.persistence.*
Continue reading
1. SQL을 직접 다룰 때 발생하는 문제점
- 반복 작업
- CRUD 각각의 기능에 해당하는 SQL문을 작성, 반복
- 객체를 관계형 DB에 저장하기 위해 CRUD를 구현하려면 너무 많은 SQL과 JDBC API를 코드로 작성해야 함(반복)
- SQL 의존적인 개발
- 기존 구현 내용에 추가적인 요구사항을 반영할 경우 CRUD 모든 SQL문을 업데이트 해야 함
- DAO(Data Access Object)의 계층 분할의 어려움
- 아래 코드처럼 DAO의 메소드가 어떤 쿼리를 날리는지 일일이 확인해보면서 개발을 해야 함(의존)
public class MemberDAO{
public Member find(String memberID){
// SELECT MEMBER_ID, TEL FROM MEMBER M
}
public Member findWithTeam(String memberID){
// SELECT MEMBER_ID, TEL, TEAM FROM MEMBER
}
}
- 정리하면?
- 진정한 의미의 계층 분할이 어려움 (애플리케이션과 DB의 계층 분할)
- 엔티티를 신뢰할 수 없음 (DAO의 SQL을 하나 하나 열어봐야 하는 문제)
- SQL에 의존적인 개발을 피하기 어려움
Continue reading