티스토리 뷰
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
- Entity의 ManyToOne의 FetchType에 대해 어떤식으로 처리되는지 정리
- JPQL을 사용했을때 발생하는 N + 1 문제를 fetch join으로 해결
1. 준비
1.1 DDL & Records
create table `member`
(
member_id bigint auto_increment primary key,
team_id bigint null,
name varchar(255) null
);
create table `team`
(
team_id bigint auto_increment primary key,
name varchar(255) null
);
# member
member_id,team_id,name
1,<null>,m1
2,1,m2
3,2,m3
4,2,m4
5,3,m5
6,3,m6
7,4,m7
8,4,m8
9,5,m9
10,5,m10
# team
team_id,name
1,team1
2,team2
3,team3
4,team4
5,team5
1.2 Entity
@Getter @Setter
@Entity @Table(name = "member")
public class Member {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "member_id")
private Long id;
private String name;
@ManyToOne(fetch = ?, cascade = CascadeType.ALL)
@JoinColumn(name = "team_id")
private Team team;
}
@Getter @Setter
@Entity @Table(name = "team")
public class Team {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "team_id")
private Long id;
private String name;
}
1.3 표출하기
Member 객체와 Team을 보기좋게 표출하기 위한 print method
public static void print(Member member) {
String memberName = member.getName();
String teamName = null;
if (member.getTeam() != null) {
teamName = member.getTeam().getName();
}
System.out.printf(">>> %s-%s%n", memberName, teamName);
}
2. EntityManager.find
2.1 실행코드
public static void logic(EntityManager em) {
Member member = em.find(Member.class, 2L);
print(member);
2.2 FetchType.EAGER 실행결과(query 1회)
Hibernate: select member0_.member_id as member_i1_0_0_, member0_.name as name2_0_0_, member0_.team_id as team_id3_0_0_, team1_.team_id as team_id1_1_1_, team1_.name as name2_1_1_ from member member0_ left outer join team team1_ on member0_.team_id=team1_.team_id where member0_.member_id=?
>>> m2-team1
2.3 FetchType.LAZY 실행결과(query 2회)
Hibernate: select member0_.member_id as member_i1_0_0_, member0_.name as name2_0_0_, member0_.team_id as team_id3_0_0_ from member member0_ where member0_.member_id=?
Hibernate: select team0_.team_id as team_id1_1_0_, team0_.name as name2_1_0_ from team team0_ where team0_.team_id=?
>>> m2-team1
3. JPQL
3.1 Single
3.1.1 실행코드
String jpql = "select m from Member m join fetch m.team where m.id=:id";
Member member = em.createQuery(jpql, Member.class)
.setParameter("id", 2L).getSingleResult();
print(member);
3.1.2 FetchType.EAGER(query 2회)
Hibernate: select member0_.member_id as member_i1_0_, member0_.name as name2_0_, member0_.team_id as team_id3_0_ from member member0_ where member0_.member_id=?
Hibernate: select team0_.team_id as team_id1_1_0_, team0_.name as name2_1_0_ from team team0_ where team0_.team_id=?
>>> m2-team1
3.1.3 FetchType.LAZY(query 2회)
Hibernate: select member0_.member_id as member_i1_0_, member0_.name as name2_0_, member0_.team_id as team_id3_0_ from member member0_ where member0_.member_id=?
Hibernate: select team0_.team_id as team_id1_1_0_, team0_.name as name2_1_0_ from team team0_ where team0_.team_id=?
>>> m2-team1
3.2 Multiple
3.2.1 실행코드
String jpql = "select m from Member m";
List<Member> resultList = em.createQuery(jpql, Member.class)
.getResultList();
for (Member member : resultList) {
print(member);
}
3.2.2 FetchType.EAGER(query 6회)
Hibernate: select member0_.member_id as member_i1_0_, member0_.name as name2_0_, member0_.team_id as team_id3_0_ from member member0_
Hibernate: select team0_.team_id as team_id1_1_0_, team0_.name as name2_1_0_ from team team0_ where team0_.team_id=?
Hibernate: select team0_.team_id as team_id1_1_0_, team0_.name as name2_1_0_ from team team0_ where team0_.team_id=?
Hibernate: select team0_.team_id as team_id1_1_0_, team0_.name as name2_1_0_ from team team0_ where team0_.team_id=?
Hibernate: select team0_.team_id as team_id1_1_0_, team0_.name as name2_1_0_ from team team0_ where team0_.team_id=?
Hibernate: select team0_.team_id as team_id1_1_0_, team0_.name as name2_1_0_ from team team0_ where team0_.team_id=?
>>> m1-null
>>> m2-team1
>>> m3-team2
>>> m4-team2
>>> m5-team3
>>> m6-team3
>>> m7-team4
>>> m8-team4
>>> m9-team5
>>> m10-team5
3.2.3 FetchType.LAZY(query 6회)
Hibernate: select member0_.member_id as member_i1_0_, member0_.name as name2_0_, member0_.team_id as team_id3_0_ from manyToOne_member member0_
>>> m1-null
Hibernate: select team0_.team_id as team_id1_1_0_, team0_.name as name2_1_0_ from manyToOne_team team0_ where team0_.team_id=?
>>> m2-team1
Hibernate: select team0_.team_id as team_id1_1_0_, team0_.name as name2_1_0_ from manyToOne_team team0_ where team0_.team_id=?
>>> m3-team2
>>> m4-team2
Hibernate: select team0_.team_id as team_id1_1_0_, team0_.name as name2_1_0_ from manyToOne_team team0_ where team0_.team_id=?
>>> m5-team3
>>> m6-team3
Hibernate: select team0_.team_id as team_id1_1_0_, team0_.name as name2_1_0_ from manyToOne_team team0_ where team0_.team_id=?
>>> m7-team4
>>> m8-team4
Hibernate: select team0_.team_id as team_id1_1_0_, team0_.name as name2_1_0_ from manyToOne_team team0_ where team0_.team_id=?
>>> m9-team5
>>> m10-team5
4. JPQL(fetch join)
fetch join을 통한 N + 1 해결
4.1 Single(FetchType.LAZY)
4.1.1 실행코드
String jpql = "select m from Member m left join fetch m.team where m.id=:id";
Member member = em.createQuery(jpql, Member.class)
.setParameter("id", 2L).getSingleResult();
print(member);
4.1.2 실행결과(query 1회)
Hibernate: select member0_.member_id as member_i1_0_0_, team1_.team_id as team_id1_1_1_, member0_.name as name2_0_0_, member0_.team_id as team_id3_0_0_, team1_.name as name2_1_1_ from member member0_ inner join team team1_ on member0_.team_id=team1_.team_id where member0_.member_id=?
>>> m2-team1
4.2 Multiple(FetchType.LAZY)
4.2.1 실행코드
String jpql = "select m from Member m left join fetch m.team";
List<Member> resultList = em.createQuery(jpql, Member.class)
.getResultList();
for (Member member : resultList) {
print(member);
}
4.2.2 실행결과(query 1회)
Hibernate: select member0_.member_id as member_i1_0_0_, team1_.team_id as team_id1_1_1_, member0_.name as name2_0_0_, member0_.team_id as team_id3_0_0_, team1_.name as name2_1_1_ from manyToOne_member member0_ left outer join manyToOne_team team1_ on member0_.team_id=team1_.team_id
>>> m2-team1
>>> m3-team2
>>> m4-team2
>>> m5-team3
>>> m6-team3
>>> m7-team4
>>> m8-team4
>>> m9-team5
>>> m10-team5
>>> m1-null
'Java > JPA' 카테고리의 다른 글
JPA, Composite Key, IdClass (0) | 2021.12.03 |
---|---|
JPA, DynamicUpdate, DynamicInsert (0) | 2021.10.28 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- onetomany
- tkinter command & bind [명령어묶기와 사건묶기] Python
- activebackground
- disabledforeground
- JPA
- 리눅스
- vba
- Linux
- apache
- IdClass
- Excel
- borderwidth
- command
- activeforeground
- highlightthickness
- ManyToOne
- 폼
- tkinter
- FetchType
- indicatoron
- Composite Key
- fetch join
- highlightbackground
- Python
- checkbutton
- 상수
- Java
- 파이썬
- Private
- Module
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
글 보관함