[스프링 JPA] WEEK 2

enxnong·2023년 9월 16일
0

김영환님의 강의 자바 ORM 표준 JPA 프로그래밍 - 기본편 보면서 공부한 내용입니다.

🏊‍♀️ 섹션 4

기본 키 매핑

📝 기본 키 매핑 어노테이션

  • @Id
    ✅ 직접 할당
  • @GeneratedValue
    ✅ 자동 생성

💡@GeneratedValue 종류

  • IDENTITY : 데이터베이스에 위임, MYSQL
    - ex) MYSQL의 AUTO_INCREMENT
  • SEQUENCE : 데이터베이스 시퀀스 오브젝트 사용, ORACLE
    - @SequenceGenerator 필요
  • TABLE : 키 생성용 테이블 사용, 모든 DB에서 사용
    - @TableGenerator 필요
  • AUTO : 방언에 따라 자동 지정, 기본값
    - ex) 오라클이면 sequence 생성

📝 IDENTITY 전략 특징

  • 기본 키 생성을 데이터베이스에 위임
  • 주로 MYSQL, 포스트그레, SQL Server, db2에서 사용
  • JPA는 보통 트랜잭션 커밋 시점에 INSERT SQL 실행
  • AUTO_INCREMENT는 데이터 베이스에 INSERT SQL을 실행한 이후에 ID값을 알 수 있음
  • IDENTITY 전략은 em.persist() 시점에 즉시 INSERT SQL 실행하고 DB에서 식별자를 조회

📝 테이블 전략 특징

  • 키 생성 전용 테이블을 하나 만들어서 데이터베이스 시퀀스를 흉내내는 전략

    장점 : 모든 데이터베이스에 적용 가능
    단점 : 성능

📝 SEQUENCE 전략 특징

  • 데이터베이스 시퀀스는 유일한 값을 순서대로 생성하는 특별한
    데이터베이스 오브젝트(예: 오라클 시퀀스)
  • 오라클, PostgreSQL, DB2, H2 데이터베이스에서 사용

📝 권장하는 식별자 전략

  • 기본 키 제약 조건: null 아님, 유일, 변하면 안된다.
  • 미래까지 이 조건을 만족하는 자연키는 찾기 어렵다. 대리키(대
    체키)를 사용하자.
    EX) 비즈니스번호, 주민등록번호(자연키)도 기본 키로 적절하기 않다.
  • 권장: Long형 + 대체키 + 키 생성전략 사용

🏊‍♀️ 섹션 5

단방향 연관관계

💡 연관관계 매핑 기초

  • 객체를 테이블에 맞추어 데이터 중심으로 모델링하면, 협력 관계를 만들 수 없다.
  • 테이블은 외래 키로 조인을 사용해서 연관된 테이블을 찾는다.
  • 객체는 참조를 사용해서 연관된 객체를 찾는다.
// 객체 지향 연관관계 사용 전

// Member.java
@Id
@GeneratedValue
@Column(name="MEMBER_ID")
private Long id;
@Column(name="USERNAME")
private String username;
@Column(name="TEAM_ID")
private Long teamId;

// Team.java
@Id @GeneratedValue
@Column(name="TEAM_ID")
private Long id;
private String name;

// Main.class
Team team = new Team();
team.setName("TeamA");
em.persist(team);

Member member = new Member();
member.setUsername("member1");
member.setTeam(team);
em.persist(member);

Member findMember = em.find(Member.class, member.getId());

Long findMemberId = findMember.getTeamId();
Team findTeam = findMemberId.getName();
// 객체 지향 연관관계 사용 후

// Member.java
@Id
@GeneratedValue
@Column(name="MEMBER_ID")
private Long id;
@Column(name="USERNAME")
private String username;
@ManyToOne // 단방향 매핑 (Team이 1. 회원이 many)
@JoinColumn(name="TEAM_ID")
private Team team;

// Main.class
Team team = new Team();
team.setName("TeamA");
em.persist(team);

Member member = new Member();
member.setUsername("member1");
member.setTeam(team);
em.persist(member);

Member findMember = em.find(Member.class, member.getId());
Team findTeam = findMember.getTeam();

양방향 연관관계

📝 양방향 매핑

  • 단방향과 양방향은 테이블 변화가 없다.
    ✅ fk를 통한 join을 통해서 연관관계를 알 수 있기 때문이다.
  • 양방향 매핑시 객체 참조할 때 서로가 연관관계 되어있는 객체를 넣어줘야 한다.
  • 객체의 양방향 관계는 사실 양방향 관계가 아니라 서로 다른 단뱡향 관계 2개다.
  • 객체를 양방향으로 참조하려면 단방향 연관관계를 2개 만들어야 한다.
// Team.java
    @Id @GeneratedValue
    @Column(name="TEAM_ID")
    private Long id;
    private String name;
    
    @OneToMany(mappedBy = "team")
    // 팀(1)에서 회원(many)로
    // Member.java에 있는 Team team에 엮여있다
    private List<Member> members = new ArrayList<Member>();

📝 연관관계의 주인

  • 객체의 두 관계중 하나를 연관관계의 주인으로 지정
    ✅ 외래키가 있는 곳을 주인으로 정해라!
    ✅ 간단하게 생각하면 1:N인 경우 N인쪽이 주인이다.
  • 연관관계의 주인만이 외래키를 관리(등록, 수정)
  • 주인이 아닌쪽은 읽기만 가능
  • 주인은 mappedBy 속성 사용X
    ✅ mappedBy가 적힌 곳은 읽기(주인이 아님)만 가능
  • 주인이 아니면 mappedBy 속성으로 주인 지정

📝 양방향 연관관계시 주의사항

  • 역방향(주인이 아닌 방향)만 연관관계 설정
public void setTeam(Team team) {
        this.team = team;
        team.getMembers().add(this); // this는 Member
    }
  • 항상 양쪽에 값을 세팅하기
  • 양방향 매핑시에 무한 루프를 조심하자
    ✅ toString(), lonmbok, JSON 생성 라이브러리

🏊‍♀️ 섹션 6

다대일 [N:1]

💡 연관관계 매핑시 고려사항 3가지
1. 다중성
✅ 다대일 : @ManyToOne
✅ 일대다 : @OneToMany
✅ 일대일 : @OneToOne
✅ 다대다 : @ManyToMany
2. 단방향, 양방향
3. 연관관계의 주인

  • N(다수) : 1
  • 다대일의 반대는 일대다
  • 외래 키가 있는 쪽(N)이 연관관계의 주인
  • 양쪽을 서로 참조하도록 개발
MemberTeam
profile
높은 곳을 향해서

0개의 댓글