Spring Data JPA - 예제 도메인 모델과 동작확인

2022. 7. 26. 19:23·공부/JPA
반응형

출처 : 인프런 실전! 스프링 데이터 JPA

Spring Data JPA 게시글은 대부분 인프런의 김영한님의 강의인 '실전! 스프링 데이터 JPA' 기반으로 내용을 정리했습니다.

 

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

  • 여러 개의 멤버가 하나의 팀에 소속될 수 있다. (다대일)
  • 하나의 팀에는 여러 명의 멤버가 소속될 수 있다. (일대다)
  • ERD에서 외래키는 다(N)쪽인 멤버에게 만들어진다.

 

Member.class

@Entity
@Getter @Setter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@ToString(of = {"id", "username", "age"})
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;


//    protected Member() { // 엔티티는 기본적으로 기본 생성자가 있어야한다.
//                        // JPA에서 프록시 기술을 쓸 때 private으로 막아져있음 제대로 기능을 사용하지 못한다.
//    }

    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 changeTeam(Team team) {
        this.team = team;
        team.getMembers().add(this);
    }
}
  • @NoArgsConstructor(access = AccessLevel.PROTECTED) : JPA 스펙상 기본 생성자를 protected로 열어둬야한다.
  • @ToString은 가급적 내부 필드만(연관관계 없는 것만. 만약 연관관계 있는 것을 걸어뒀을 시 에러가 발생할 수 있다.)
  • chageTeam()으로 양방향 연관관계 한 번에 처리

 

Team.class

@Entity
@Getter @Setter
@NoArgsConstructor(access= AccessLevel.PROTECTED)
@ToString(of={"id", "name"})
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이 연관관계의 주인이기 때문에 Team.members는 연관관계의 주인이 아니다. 따라서 Member.team이 데이터베이스 외래키 값을 변경할 수 있고, Team.members는 읽기만 가능하기 때문에 mappedBy 속성을 준다.

 

MemberTest.class

@SpringBootTest
@Transactional
@Rollback(false)
class MemberTest {

    @PersistenceContext
    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("member = " + member);
            System.out.println("-> member.team = " + member.getTeam());
        }
    }

}
2022-07-26 19:16:45.177 DEBUG 31239 --- [           main] org.hibernate.SQL                        : 
    select
        member0_.member_id as member_i1_0_,
        member0_.age as age2_0_,
        member0_.team_id as team_id4_0_,
        member0_.username as username3_0_ 
    from
        member member0_
member = Member(id=3, username=member1, age=10)
2022-07-26 19:16:45.209 DEBUG 31239 --- [           main] org.hibernate.SQL                        : 
    select
        team0_.team_id as team_id1_1_0_,
        team0_.name as name2_1_0_ 
    from
        team team0_ 
    where
        team0_.team_id=?
-> member.team = Team(id=1, name=teamA)
member = Member(id=4, username=member2, age=20)
-> member.team = Team(id=1, name=teamA)
member = Member(id=5, username=member3, age=30)
2022-07-26 19:16:45.221 DEBUG 31239 --- [           main] org.hibernate.SQL                        : 
    select
        team0_.team_id as team_id1_1_0_,
        team0_.name as name2_1_0_ 
    from
        team team0_ 
    where
        team0_.team_id=?
-> member.team = Team(id=2, name=teamB)
member = Member(id=6, username=member4, age=40)
-> member.team = Team(id=2, name=teamB)
  • 순수 JPA로 동작(추후 변경)
  • DB 테이블 결과 확인

  • 지연 로딩 동작 확인
반응형
저작자표시 비영리 변경금지 (새창열림)
'공부/JPA' 카테고리의 다른 글
  • Spring Data JPA - 공통 인터페이스
  • Spring Data JPA - 순수 JPA 기반 리포지토리 만들기
  • Spring Data JPA - 프로젝트 환경 설정
  • JPA 객체지향 쿼리 언어(JPQL) - 벌크 연산
데부한
데부한
어차피 할 거면 긍정적으로 하고 싶은 개발자
    반응형
  • 데부한
    동동이개발바닥
    데부한
  • 전체
    오늘
    어제
    • 분류 전체보기 (307)
      • 방통대 컴퓨터과학과 (27)
        • 잡담 (9)
        • 3학년1학기 (17)
      • 프로젝트 및 컨퍼런스 회고 (1)
        • 프로젝트 (4)
        • 한이음 프로젝트 (0)
        • 회고 (3)
      • 공부 (165)
        • Spring (37)
        • JPA (71)
        • 인프런 워밍업 클럽_BE (10)
        • Java (6)
        • React.js (27)
        • 넥사크로 (11)
        • 기타 (3)
      • 알고리즘 (85)
        • 알고리즘 유형 (10)
        • 알고리즘 풀이 (57)
        • SQL 풀이 (18)
      • 에러 해결 (13)
      • 잡담 (7)
        • 국비교육 (2)
        • 구매후기 (5)
        • 진짜 잡담 (0)
  • 블로그 메뉴

    • Github
    • Linkedin
    • 홈
    • 방명록
    • 글쓰기
    • 관리
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    에러해결
    oracle
    방통대
    알고리즘
    JPA
    RESTful
    운영체제
    토이프로젝트
    자바스크립트
    egov
    Java
    react
    프론트엔드
    Spring
    springboot
    개발자
    인프런
    SQL
    전자정부프레임워크
    MSA
    기출문제
    토비의스프링부트
    스프링부트
    코딩테스트
    프로그래머스
    IT
    넥사크로
    QueryDSL
    SpringBoot를 이용한 RESTful Web Service 개발
    백준
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
데부한
Spring Data JPA - 예제 도메인 모델과 동작확인
상단으로

티스토리툴바