| 구분 | 설명 |
|---|---|
| 단방향 | 한 엔티티가 다른 엔티티만 참조 |
| 양방향 | 서로가 서로의 엔티티를 참조 |
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "FK_필드명")
private ParentEntity parent;
@OneToMany(mappedBy = "parent")
@ToString.Exclude // 순환 참조 방지
@Builder.Default // 빌더 패턴 사용 시 초기값 유지
private List<ChildEntity> childList = new ArrayList<>();
💡 Tip:
mappedBy는 참조할 변수명을 명시하며, FK의 주인은@ManyToOne쪽이다.
| 옵션 | 설명 |
|---|---|
CascadeType.ALL | 부모가 삭제/수정/저장되면, 자식도 같이 처리 |
CascadeType.PERSIST | 부모 저장 시, 자식도 함께 저장 |
CascadeType.MERGE | 부모 수정 시, 자식도 함께 수정 |
CascadeType.REMOVE | 부모 삭제 시, 자식도 함께 삭제 |
CascadeType.REFRESH | 부모 재호출 시, 자식도 재호출 |
CascadeType.DETACH | 부모 영속 해제 시, 자식도 함께 영속 해제 |
⚠️ 주의:
CascadeType.ALL은 편리하지만, 실수로 모든 자식이 삭제될 수 있으므로 신중히 사용해야 한다.
| 옵션 | 설명 | 특징 |
|---|---|---|
FetchType.EAGER | 엔티티 조회 시 즉시 조회 | 초기 로딩이 느리고 불필요한 데이터까지 조회 |
FetchType.LAZY | 엔티티 조회 시 지연 조회 | 초기 로딩이 빠르고 필요할 때만 참조 객체를 조회 |
💡
FetchType.LAZY는 성능 최적화에 유리하며, 실무에서 기본적으로 권장된다.
(필요한 시점에참조엔티티.getXXX()를 통해 로딩)
| 형태 | 설명 |
|---|---|
findBy필드명(String 필드값) | SELECT * FROM 테이블명 WHERE 필드명 = ? |
findBy이름And나이(String name, int age) | 다중 조건 검색 |
findBy이름Containing(String keyword) | LIKE 검색 (부분 일치) |
⚙️ 주의:
- 반드시 카멜 표기법(CamelCase) 을 사용해야 한다.
- 필드명은 Entity의 변수명 기준으로 작성한다.
public interface MemberRepository extends JpaRepository<Member, Long> {
List<Member> findByUsername(String username);
List<Member> findByAgeGreaterThan(int age);
List<Member> findByEmailContaining(String email);
}
@Query(value = "SELECT * FROM member WHERE email = :email", nativeQuery = true)
Member findByEmail(@Param("email") String email);
| 속성 | 설명 |
|---|---|
value | 실행할 SQL 문장 |
nativeQuery | true → 네이티브 SQL로 실행 |
:매개변수명 | 파라미터 바인딩 |
💡 네이티브 쿼리는 SQL의 강력한 기능을 활용할 수 있지만, DB 종속성이 생긴다.