ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 2. 예제 도메인 개발
    스프링/spring data jpa 2023. 2. 15. 22:22

    예제 도메인 엔티티 ERD

    엔티티 코드

    Member.java

    package study.datajpa.entity;
    
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.FetchType;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.JoinColumn;
    import javax.persistence.ManyToOne;
    
    import lombok.AccessLevel;
    import lombok.Getter;
    import lombok.NoArgsConstructor;
    import lombok.Setter;
    import lombok.ToString;
    
    @Entity
    @Getter @Setter
    @NoArgsConstructor(access = AccessLevel.PROTECTED)    // jpa 는 내부적으로 리플렉션을 사용하기 때문에 기본생성자가 필요하다.
    @ToString(of = {"id", "username", "age"}) // team 쓰면 무한 루프가 일어날 수도 있어서 가급적이면 toString에 안쓰는게 좋다.
    public class Member {
    
    	@Id
    	@GeneratedValue(strategy = GenerationType.IDENTITY)
    	@Column(name = "member_id") // @Column name 속성 : 데이터베이스 테이블과 매핑되는 이름으로 맞춰준다.
    	private Long id;
    	private String username;
    	private int age;
    
    	// 연관관계매핑 : 자신 엔티티 To 상대 엔티티, 연관관계 주인, fetch 전략
    	@ManyToOne(fetch = FetchType.LAZY)
    	@JoinColumn(name = "team_id") // fk 명 연결
    	private Team team;
    
    	public Member(String username) {
    		this.username = username;
    	}
    
    	public Member(String username, int age, Team team) {
    		this.username = username;
    		this.age = age;
    		this.team = team;
    	}
    
    	public void changeTeam(Team team) {
    		this.team = team;
    		team.getMembers().add(this); // 객체 연관관계이기 때문에 team 에도 member 를 추가해주었다.
    	}
    }
    • NoArgsConstructor(access = AccessLevel.PROTECTED)
      • JPA는 내부적으로 리플렉션을 사용하기 때문에 기본생성자가 필요함.
      • 기본생성자는 리플렉션 용도 이외에 외부에서 사용될 일이 없으므로, 잘못 호출되는 것을 방지하기 위해 접근제한자를 protected(자신 + 상속한 클래스) 로 설정.
    • ToString은 연관관계 매핑이 있는 엔티티는 가급적 사용하면 안된다. A가 B를 호출하고, B가 A를 호출하는 무한루프에 빠질 수 있다.
    • @Column 의 name 속성은 데이터베이스 테이블 컬럼명을 엔티티 클래스 필드에 매핑하기 위해 사용한다.

    Team.java

    package study.datajpa.entity;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.OneToMany;
    
    import lombok.AccessLevel;
    import lombok.Getter;
    import lombok.NoArgsConstructor;
    import lombok.Setter;
    import lombok.ToString;
    
    @Getter @Setter
    @Entity
    @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") // foreign key 가 없는 쪽에 mappedBy를 걸어야한다.
    	private List<Member> members = new ArrayList<>();
    
    	public Team(String name) {
    		this.name = name;
    	}
    }

    테스트 코드

    package study.datajpa.entity;
    
    import java.util.List;
    
    import javax.persistence.EntityManager;
    import javax.persistence.PersistenceContext;
    
    import org.junit.jupiter.api.Test;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.annotation.Rollback;
    import org.springframework.transaction.annotation.Transactional;
    
    @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()); // 지연로딩으로 적용된다.
    		}
    	}
    }

     

    '스프링 > spring data jpa' 카테고리의 다른 글

    1. 프로젝트 설정 및 테스트  (0) 2023.02.15
Designed by Tistory.