728x90
1. 객체를 테이블에 맞춰 데이터 중심으로 모델링 했을 때
이 방식으로 모델링을 하면 객체지향과 거리가 멀어진다.
왜 객체의 참조와 외래키를 매핑해야되는지 예시를 보며 이해해보자.
Member와 Team은 N:1 관계라고 하자.
✅Member
package hellojpa;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
@Entity
@Getter
@Setter
public class Member {
@Id
@GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
@Column(name = "USERNAME")
private String username;
@Column(name="TEAM_ID")
private Long teamId;
}
✅Team
package hellojpa;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import lombok.Getter;
import lombok.Setter;
@Entity
@Getter
@Setter
public class Team {
@Id
@GeneratedValue
@Column(name = "TEAM_ID")
private Long id;
private String name;
}
✅Main() 실행부
package hellojpa;
import jakarta.persistence.*;
public class JpaMain {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
try{
Team team = new Team();
team.setName("TeamA");
em.persist(team); //TEAM_ID값이 자동생성
//Member 객체 테이블에 추가
Member member = new Member();
member.setUsername("member1");
//MEMBER테이블에 TEAM_ID값을 저장하려면 team에서 Id를 찾아와야함.
//외래키 식별자를 직접 다뤄야함.
member.setTeamId(team.getId());
em.persist(member);
//Member가 속한 Team이 무엇인지 조회
//Team을 바로 가져올 수 없음
//아래처럼 member의 teamId가 무엇이고 그 teamId에 해당하는 Team이 무엇인지, DB에 계속 확인해야됨.
Member findMember = em.find(Member.class, member.getId());
Long findTeamId = findMember.getTeamId();
Team findTeam = em.find(Team.class, findTeamId);
tx.commit();
}catch (Exception e){
tx.rollback();
}finally {
em.close();
}
}
}
💡 왜 객체의 참조와 외래키를 매핑해야할까?
✔️ 데이터베이스에서는 외래 키와 JOIN을 사용하여 테이블 간의 관계를 정의하고 데이터를 조회한다.
SELECT * FROM member m
JOIN team t ON m.team_id = t.id
✔️ 객체 지향 프로그래밍에서는 객체가 다른 객체를 참조하여 관계를 정의한다.
public class Member {
private Long id;
private Team team; //다른 객체를 참조
// getters and setters
}
public class Team {
private Long id;
private String name;
// getters and setters
}
✔️ JPA를 사용할 때, 객체의 참조와 외래 키를 매핑을 해야 객체 지향 설계 원칙을 따르면서 데이터베이스와의 상호 작용을 원활하게 할 수 있다.
2. 객체의 참조와 외래키를 매핑했을 때
객체지향적으로 JPA를 사용하는 법을 코드로 보자.
✅Member
package hellojpa;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
@Entity
@Getter
@Setter
public class Member {
@Id
@GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
@Column(name = "USERNAME")
private String username;
@ManyToOne //Member와 Team은 N:1
@JoinColumn(name = "TEAM_ID")
private Team team;
}
데이터 중심 모델링 코드와 달리 TEAM_ID를 세팅하지않고 Team 객체를 참조한다.
그리고 참조하는 객체와의 관계(@ManyToOne)와 어떤 컬럼을 조인해서 가져올지(@JoinColum) 명시해주면 된다.
✅Team
데이터 중심 모델링 코드와 동일하다.
✅Main() 실행부
package hellojpa;
import jakarta.persistence.*;
public class JpaMain {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
try{
//저장
Team team = new Team();
team.setName("TeamA");
em.persist(team);
Member member = new Member();
member.setUsername("member1");
member.setTeam(team);//member.setTeamId(team.getId()); 이렇게 외래키 식별자를 직접 다룰 필요가 없다.
em.persist(member);
//Member가 속한 Team 조회하기
Member findMember = em.find(Member.class, member.getId());
Team findTeam = findMember.getTeam();
//이전 코드는 Member에서 teamId를 찾고 이 teamId로 다시 Team을 찾아야했다.
//이제 이런 코드가 필요없고 Team객체를 참조해서 getTeam을 하면 끝
//Long findTeamId = findMember.getTeamId();
//Team findTeam = em.find(Team.class, findTeamId);
System.out.println("findTeam = " + findTeam.getName());
tx.commit();
}catch (Exception e){
tx.rollback();
}finally {
em.close();
}
}
}
객체 참조하지 않고 데이터 중심으로 모델링했을 때와 달리, 외래키 식별자를 하나하나 찾아와서 Team을 찾아내는 코드가 필요없어졌다.
이렇게 연관관계 매핑을 통해 객체지향적인 방식으로 JPA를 다룰 수 있다.
728x90
'인프런 김영한 강의 정리 > 자바 ORM 표준 JPA 프로그래밍 기본편' 카테고리의 다른 글
JPA 기본 | 다양한 연관관계 매핑 (0) | 2024.07.05 |
---|---|
JPA 기본 | 양방향 연관관계와 연관관계의 주인 (0) | 2024.07.02 |
H2 새로운 데이터베이스로 접속 오류 해결하기 (0) | 2024.06.10 |
JPA 기본 | 기본키 매핑 | @id, @GeneratedValue (0) | 2024.06.10 |
JPA 기본 | 필드와 컬럼 매핑 | @Column, @Enumerated, @Temporal, @Lob (0) | 2024.06.10 |