https://www.inflearn.com/course/Querydsl-%EC%8B%A4%EC%A0%84/
강의를 들으며 생각 정리
예제 도메인 모델과 동작확인
앞으로 Querydsl 학습시 사용할 예제 도메인 모델을 설계하자.
도메인 모델은 단순하게 회원(Member) - 팀(Team) 엔티티가 다대일 양방향 연관관계를 맺도록 설계한다.
</entity/Member>
@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;
public Member(String username) {
this(username, 0);
}
public Member(String username, int age) {
this(username, age, null);
}
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);
}
}
</entity/Team>
@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;
}
}
@Setter : 실무에서 가급적 Setter는 사용하지 않는다. 지금은 공부를 위해서 열어둔다.
@NoArgsConstructor AccessLevel.PROTECTED : JPA 스펙상 기본 생성자를 열어두어야 한다. 외부에서 기본 생성자로 접근하는 것을 막기 위해 protected로 열어둔다.
@ToString : 가급적 내부 필드만 출력 (연관관계인 엔티티를 ToString에 포함하면 무한루프의 위험성이 있다)
Member -> changeTeam() : 양방향 연관관계 한번에 처리 (연관관계 편의 메서드)
+) Member가 Team을 바꾸면 기존 team.getMembers()에서는 Member를 삭제해야 하지 않나?
: Team은 연관관계의 주인이 아니므로 JPA 동작에 영향을 주지 않기 때문에 따로 삭제할 필요 없다. Member가 연관관계의 주인이고 DB에서 연관관계를 나타낼 때, Member 테이블의 외래키에만 의존한다.
확실하게 컬렉션에서 삭제를 해도 되지만 너무 복잡해지고, JPA와 DB 변경에 영향을 주지 않아서 이런 부분은 생략해도 된다.
간단하게 테스트 해본다.
@SpringBootTest
@Transactional
class MemberTest {
@Autowired
private EntityManager em;
@Test
public void testEntity() {
//given
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();
//when
List<Member> members = em.createQuery("select m from Member m", Member.class)
.getResultList();
//then
for (Member member : members) {
System.out.println("member = " + member);
System.out.println("-> member.team = " + member.getTeam());
}
}
}
-> DB 테이블 결과 확인, 지연 로딩 동작 확인
'java > querydsl' 카테고리의 다른 글
[Querydsl] 실무 활용 - 스프링 데이터 JPA와 Querydsl (0) | 2021.06.06 |
---|---|
[Querydsl] 실무 활용 - 순수 JPA와 Querydsl (0) | 2021.06.04 |
[Querydsl] 중급 문법 (1) | 2021.06.03 |
[Querydsl] 기본 문법 (0) | 2021.06.02 |
[Querydsl] 프로젝트 환경설정 (0) | 2021.06.01 |