본문 바로가기
웹개발/Springboot

ORM / 양방향 매핑 원리

by HoPpangg 2021. 7. 17.
SMALL

테이블 조인을 할 때 전략을 바꿀 수 있습니다. 

컬렉션 값에 대해서 default 값은 lazy loding으로 처음 select가 일어날 때 컬렉션은 select 하지 않고 컬렉션이 필요할 때 다시 select를 해서 컬렉션의 데이터를 불러오는 방식입니다. 이때는 select가 두번 일어나기 때문에 IO도 두번 일어나게 됩니다.

이렇게 @OneToMany annotation 안에 fetch값을 EAGER로 해주면 서버 실행 시 컬렉션을 join 합니다.

 

Post 테이블에서 User는 컬렉션 타입이 아니기때문에 EAGER가 default 값입니다.

user 테이블의 @OneToMany annotation의 fetch 값을 EAGER로 설정하고 아래 메서드를 실행해보면

콘솔창을 확인해보면

Hibernate: select user0_.id as id1_1_0_, user0_.address as address2_1_0_, user0_.email as email3_1_0_, user0_.password as
 password4_1_0_, user0_.userid as userid5_1_0_, posts1_.user_id as user_id4_0_1_, posts1_.id as id1_0_1_, posts1
_.id as id1_0_2_, posts1_.content as content2_0_2_, posts1_.title as title3_0_2_, posts1_.user_id as user_id4_0_2_ 
from user user0_ left outer join post posts1_ on user0_.id=posts1_.user_id where user0_.id=?

 

left outer join을 하는 것을 볼 수 있습니다.

 

하지만 @OneToManyAnnotation의 fetch 값을 LAZY로 설정하고 같은 메서드를 실행해보면

 

콘솔창을 확인해보면

 

Hibernate: select user0_.id as id1_1_0_, user0_.address as address2_1_0_, user0_.email as email3_1_0_, user0_.pa
ssword as password4_1_0_, user0_.userid as userid5_1_0_ from user user0_ where user0_.id=?

 

select 만 하는 것을 볼 수 있습니다.

 

그렇다면 @OneToManyAnnotation의 fetch 값을 LAZY로 설정하고 아래 메서드를 통해서 post를 get 해봅시다

콘솔창을 보면

 

Hibernate: select user0_.id as id1_1_0_, user0_.address as address2_1_0_, user0_.email as email3_1_0_, user0_.pa
ssword as password4_1_0_, user0_.userid as userid5_1_0_ from user user0_ where user0_.id=?
Before
Hibernate: select posts0_.user_id as user_id4_0_0_, posts0_.id as id1_0_0_, posts0_.id as id1_0_1_, posts0_.conte
nt as content2_0_1_, posts0_.title as title3_0_1_, posts0_.user_id as user_id4_0_1_ from post posts0_ where post
s0_.user_id=?
After

 

post의 정보를 가져올 때 select가 다시 되는 것을 볼 수 있습니다.

 

그렇다면 이번에는 fetch 값을 EAGER로 설정하고 다시 같은 메서드를 실행시켜봅니다.

콘솔창을 보면

 

Hibernate: select user0_.id as id1_1_0_, user0_.address as address2_1_0_, user0_.email as email3_1_0_, user0_.pa
ssword as password4_1_0_, user0_.userid as userid5_1_0_, posts1_.user_id as user_id4_0_1_, posts1_.id as id1_0_
1_, posts1_.id as id1_0_2_, posts1_.content as content2_0_2_, posts1_.title as title3_0_2_, posts1_.user_id as user
_id4_0_2_ from user user0_ left outer join post posts1_ on user0_.id=posts1_.user_id where user0_.id=?
Before
After

 

애초에 처음 userEntity를 가져올 때 left outer join을 통해서 post에 대한 데이터를 가져왔기 때문에 post를 get 했을 때 select가 다시 한번 일어나지 않게됩니다.

 

post 테이블에서 ManyToOne annotation에 fetch 값을 설정하지 않고 default 값으로 둔 뒤 아래 메서드를 실행해봅니다.

콘솔창을 보면

 

Hibernate: select post0_.id as id1_0_0_, post0_.content as content2_0_0_, post0_.title as title3_0_0_, post0_.user_
id as user_id4_0_0_, user1_.id as id1_1_1_, user1_.address as address2_1_1_, user1_.email as email3_1_1_, user1_
.password as password4_1_1_, user1_.userid as userid5_1_1_ from post post0_ left outer join user user1_ on po
st0_.user_id=user1_.id where post0_.id=?
Hibernate: select posts0_.user_id as user_id4_0_0_, posts0_.id as id1_0_0_, posts0_.id as id1_0_1_, posts0_.conte
nt as content2_0_1_, posts0_.title as title3_0_1_, posts0_.user_id as user_id4_0_1_ from post posts0_ where post
s0_.user_id=?

 

처음 select에서 left outer join을 하는 것을 볼 수 있습니다. default 값이 EAGER이기 때문에 실행되면서 바로 조인을 하게 되는 것입니다. 그렇다면 여기서 user 테이블의 데이터를 get 하면 어떻게 될까요?

 

위의 메서드를 실행하고 콘솔창을 보면

 

Hibernate: select post0_.id as id1_0_0_, post0_.content as content2_0_0_, post0_.title as title3_0_0_, post0_.user_
id as user_id4_0_0_, user1_.id as id1_1_1_, user1_.address as address2_1_1_, user1_.email as email3_1_1_, user1_
.password as password4_1_1_, user1_.userid as userid5_1_1_ from post post0_ left outer join user user1_ on po
st0_.user_id=user1_.id where post0_.id=?
Hibernate: select posts0_.user_id as user_id4_0_0_, posts0_.id as id1_0_0_, posts0_.id as id1_0_1_, posts0_.conte
nt as content2_0_1_, posts0_.title as title3_0_1_, posts0_.user_id as user_id4_0_1_ from post posts0_ where post
s0_.user_id=?
Before
After

 

user데이터를 getter를 통해 가져왔지만 다시 select 하지 않는 것을 볼 수 있습니다.

 

그렇다면 @ManyToOne의 fetch 값을 LAZY로 설정해주고 같은 메서드를 실행하면 어떻게 될까요?

 

 

Hibernate: select post0_.id as id1_0_0_, post0_.content as content2_0_0_, post0_.title as title3_0_0_, post0_.user_
id as user_id4_0_0_ from post post0_ where post0_.id=?
Before
Hibernate: select user0_.id as id1_1_0_, user0_.address as address2_1_0_, user0_.email as email3_1_0_, user0_.pa
ssword as password4_1_0_, user0_.userid as userid5_1_0_, posts1_.user_id as user_id4_0_1_, posts1_.id as id1_0_
1_, posts1_.id as id1_0_2_, posts1_.content as content2_0_2_, posts1_.title as title3_0_2_, posts1_.user_id as user
_id4_0_2_ from user user0_ left outer join post posts1_ on user0_.id=posts1_.user_id where user0_.id=?
After

 

처음 실행 시에는 select만 하고 getter를 사용해서 user 데이터를 가져올 때 다시 select 하면서 left outer join을 하는 것을 볼 수 있습니다.

728x90
LIST

'웹개발 > Springboot' 카테고리의 다른 글

open-in-view  (0) 2021.07.18
양방향 매핑 - @OneToMany, @JasonIgnoreProperties  (0) 2021.07.17
DB 데이터 활용하기 - jpa 테이블 join  (0) 2021.07.04

댓글