Spring/Spring Data JPA

[Spring Data JPA] 1. 예제 도메인 모델

yoon_seon 2023. 5. 17. 17:03

예제 도메인 모델

1. 예제 도메인 모델과 동작확인


📌 예제 도메인 모델과 동작확인

Member와 Team 엔티티를 구현하고 연관관계를 테스트한다.

 

엔티티 클래스

  • Member 입장에서 다 수의 회원은 하나의 팀에 소속될 수 있다. → 다(N) 대 일(1) 관계
  • Team 입장에서 하나의 팀에는 다 수의 회원이 소속될 수 있다. 일(1) 대 다(N) 관계

 

ERD

  • 외래키(FK)는 Member가 갖는다.

 

Member 엔티티

@Entity
@Getter @Setter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@ToString(exclude = "team")
public class Member {
    @Id
    @GeneratedValue
    @Column(name = "member_id")
    private Long id;
    private String username;
    private int age;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "team_id")
    private Team team;

    public Member(String username) {
        this.username = username;
    }

    public Member(String username, int age, Team team) {
        this.username = username;
        this.age = age;
        if (team != null) {
            changeTeam(team);
        }
    }

    public void changeUsername(String username) {
        this.username = username;
    }

    public void changeTeam(Team team) {
        this.team = team;
        team.getMembers().add(this);
    }
}
  • @Setter
    실무에서는 가급적 Setter를 사용을 지양해야한다
  • @NoArgsConstructor(access = AccessLevel.PROTECTED)
    리플렉션을 통해 프록시객체를 조회하는 JPA 스팩상 접근제어자를 protected로 열어두어야 한다.
  • @ToString 
    연관관계가 없는 필드만 조회되도록 설정해야한다.
  • chagneTeam()으로 양방향 연관관계를 한번에 처리한다(연관관계 편의 메서드)

 

Team 엔티티

@Entity
@Getter @Setter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@ToString(exclude = "members")
public class Team {

    @Id
    @GeneratedValue
    @Column(name = "team_id")
    private Long id;
    private String name;

    @OneToMany(mappedBy = "team")
    private List<Member> members = new ArrayList<>();

    public Team(String name) {
        this.name = name;
    }
}
  • Member와 Team은 양방향 연관관계이고, Member.team이 연관관계의 주인(외래키 보유)이다.
  • Team.members는 연관관계의 주인이 아니기에(Member FK 없음) 읽기만 가능하다.

 

데이터 확인 테스트

@SpringBootTest
@Transactional
class MemberTest {

    @PersistenceContext
    public EntityManager em;

    @Test
    public void testEntity() {
        Team teamA = new Team("teamA");
        Team teamB = new Team("teamB");
        em.persist(teamA);
        em.persist(teamB);

        Member member1 = new Member("member1", 10, teamA);
        Member member2 = new Member("member2", 20, teamA);
        Member member3 = new Member("member3", 30, teamB);
        Member member4 = new Member("member4", 40, teamB);
        em.persist(member1);
        em.persist(member2);
        em.persist(member3);
        em.persist(member4);

        em.flush();
        em.clear();

        List<Member> members = em.createQuery("select m from Member m ", Member.class)
                .getResultList();

        for (Member member : members) {
            System.out.println("team : "+member.getTeam()+" member : "+ member);
        }
    }

}

 

  • 테스트 확인 요소
    • DB 테이블 결과 확인
    • 지연 로딩 동작 확인

 

 


해당 글은 인프런의 [실전! 스프링 데이터 JPA] 강의를 정리한 내용입니다.

 

실전! 스프링 데이터 JPA - 인프런 | 강의

스프링 데이터 JPA는 기존의 한계를 넘어 마치 마법처럼 리포지토리에 구현 클래스 없이 인터페이스만으로 개발을 완료할 수 있습니다. 그리고 반복 개발해온 기본 CRUD 기능도 모두 제공합니다.

www.inflearn.com