์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” EntityGraph์˜ ์‚ฌ์šฉ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๋ ค๊ณ  ํ•œ๋‹ค.

Entity๊ตฌ์„ฑ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค

@Entity
class Team(
    var title: String,
) {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY) // DB์—์„œ ์ž๋™์œผ๋กœ ID increment
    @Column(name = "team_id")
    var id: Long = 0L
    
    // Onwer Entity๋ฅผ Player๋กœ ์ง€์ •, Lazy type fetch, Persistence ์ „์ด ํƒ€์ž…
    @OneToMany(mappedBy="team", cascade=[CascaseType.ALL], fetch = FetchType.LAZY) 
    var players : MutableList<Player> = mutableListOf()
}

@Entity
class Player(
    var name : String,
    
    @ManyToOne
    @JoinColumn(name = "team_id") // ์™ธ๋ž˜ํ‚ค ๋งคํ•‘์„ ์œ„ํ•œ ์„ค์ •
    var game: Game
) {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY) // DB์—์„œ ์ž๋™์œผ๋กœ ID increment
    @Column(name = "player_id")
    var id: Long = 0L
    
    var count : Long
}

Game <--> Player ์—”ํ‹ฐํ‹ฐ๊ฐ€ 1:N์œผ๋กœ ์„ค์ •๋˜์–ด ์žˆ๋‹ค.

ํ˜„์žฌ Team์˜ players๋Š” LAZY type์œผ๋กœ ๊ฐ€์ ธ์˜ค๊ฒŒ ๋˜์–ด์žˆ๋Š”๋ฐ,

ํ•˜๋‚˜์˜ team.players ์กฐํšŒ์‹œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด 2๊ฐœ์˜ query๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค.

select 
team0_.team_id as team_id1_3_0_, 
team0_.name as name2_3_0_ 
from 
team team0_ 
where 
team0_.team_id=?

select 
players0_.team_id as team_id4_1_0_, 
players0_.player_id as player_i1_1_0_, 
players0_.player_id as player_i1_1_1_, 
players0_.count as count2_1_1_, 
players0_.name as name3_1_1_, 
players0_.team_id as team_id4_1_1_ 
from 
player players0_ 
where 
players0_.team_id=?

๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์˜ ๊ธ€๋“ค์„ ๋ณด๋‹ˆ, ์—ฌ๊ธฐ์—์„œ N + 1๊ฐœ์˜ Query๋ฌธ์ด ๋ฐœ์ƒํ•œ๋‹ค๊ณ  ํ•˜๋˜๋ฐ,

Fetch type์„ EAGER, LAZY๋กœ ๋ณ€๊ฒฝํ•˜๊ณ  ๋‹ค๋ฅธ ์˜ต์…˜๋“ค์„ ๋งŒ์ ธ๋ณด์•„๋„

Query๋ฌธ์€ ๋™์ผํ•˜๊ฒŒ 2๊ฐœ๋งŒ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

(์•„์ง JPA ORM๊ณผ ์นœ์ˆ™ํ•˜์ง€ ์•Š์•„์„œ ๋ชป๋‹ค๋ฃจ๋Š” ๊ฒƒ ์ผ์ˆ˜๋„ ์žˆ๋‹ค..)

 

ํ•˜์ง€๋งŒ ํ•˜๋‚˜์˜ request์— ๋Œ€ํ•ด 2๊ฐœ์˜ ์ฟผ๋ฆฌ๋ฌธ์ด ์ƒ๊ธฐ๋Š” ๊ฒƒ๋„ ์ด์ƒ์ ์ด์ง€๋Š” ์•Š๊ธฐ์—,

ํ•˜๋‚˜์˜ left outer join Query ๋ฅผ ๋งŒ๋“ค์–ด ๋ณด์ž.

Team Repository์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด @EntityGraph๋ฅผ ์„ค์ •ํ•œ๋‹ค.

interface TeamRepository : CrudRepository<Team, Long> {
    @EntityGraph(attributePaths = ["players"])
    override fun findById(id: Long): Optional<Team>
}

๋ณ€๊ฒฝ ํ›„์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด Query๊ฐ€ ๋‚˜๊ฐ€๊ฒŒ ๋œ๋‹ค.

select 
team0_.team_id as team_id1_3_0_, 
team0_.name as name2_3_0_, 
players1_.team_id as team_id4_1_1_, 
players1_.player_id as player_i1_1_1_, 
players1_.player_id as player_i1_1_2_, 
players1_.count as count2_1_2_, 
players1_.name as name3_1_2_, 
players1_.team_id as team_id4_1_2_ 
from 
team team0_ 
left outer join 
player players1_ 
on 
team0_.team_id=players1_.team_id 
where 
team0_.team_id=?

 

์ด๋กœ ์ธํ•ด fetch type EAGER์™€๋„ ๋น„์Šทํ•œ ๊ฒฐ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.

 

์˜ค๋Š˜์€ ์—ฌ๊ธฐ๊นŒ์ง€..

ํ‹€๋ฆฐ ๋‚ด์šฉ์— ๋Œ€ํ•œ ์ง€์ ์€ ์–ธ์ œ๋“ ์ง€ ํ™˜์˜์ž…๋‹ˆ๋‹ค

'Coding > SpringBoot' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[SpringBoot] Kotlin - Database Lock - 1  (0) 2021.04.21

+ Recent posts