[Spring Boot - ๐ŸฑPetClinic๐Ÿถ] 11. Repository ๋ถ„์„๐Ÿ”

์‘ค๋ฐยท2023๋…„ 4์›” 25์ผ

[Spring Boot - ๐ŸฑPetClinic๐Ÿถ]

๋ชฉ๋ก ๋ณด๊ธฐ
11/11

๐Ÿ—’ Repository

์ด์ „ ๊ธ€์—์„œ ์ •๋ฆฌํ–ˆ๋“ฏ Repository๋Š” Spring์—์„œ ์ œ๊ณตํ•˜๋Š” ๋ชจ๋“ˆ์ธ Spring Data Jpa์˜ ์ธํ„ฐํŽ˜์ด์Šค๋‹ค. ๊ฐœ๋ฐœ์ž๋Š” ์ด Repository ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ƒ์†๋ฐ›์•„ ๋ฉ”์„œ๋“œ ์ด๋ฆ„๋งŒ ์ž˜ ์ž‘์„ฑํ•˜๋ฉด JPA๊ฐ€ ์ด๋ฅผ ํ† ๋Œ€๋กœ ์ฟผ๋ฆฌ๋ฌธ์„ ๋งŒ๋“ค์–ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

์ฟผ๋ฆฌ๋ฌธ์ด ๋ณต์žกํ•˜๊ฑฐ๋‚˜ JPA๊ฐ€ ์ž๋™ ์ƒ์„ฑํ•˜๋Š” ์ฟผ๋ฆฌ๋ฌธ๊ณผ ๋‹ค๋ฅธ ์ฟผ๋ฆฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ @Query ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด ์ฟผ๋ฆฌ๋ฌธ์„ ์ง์ ‘ ์ž‘์„ฑํ•œ๋‹ค. ๋ฉ”์„œ๋“œ ์ด๋ฆ„ ์œ„์— ์ถ”๊ฐ€ํ•˜๋ฉด ๋œ๋‹ค.

@Transactional ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด ACID ๊ด€๋ จ ์„ค์ •์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค. ์—ฌ๊ธฐ์„œ ACID๋ž€ Atomicity, Consistency, Isolation, Durability์˜ ์•ž ๊ธ€์ž๋ฅผ ๋”ด ๊ฒƒ์œผ๋กœ ์›์ž์„ฑ, ์ผ๊ด€์„ฑ, ๊ฒฉ๋ฆฌ์„ฑ, ์ง€์†์„ฑ์„ ๋œปํ•œ๋‹ค. ๋” ์ž์„ธํ•˜๊ฒŒ ์„ค๋ช…ํ•˜์ž๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • Atomicity(์›์ž์„ฑ): ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์‹œ์Šคํ…œ์—์„œ ํ•œ ํŠธ๋žœ์žญ์…˜ ๋‚ด์˜ ์ž‘์—…์€ ์ค‘๊ฐ„์— ๋ฉˆ์ถค์ด ์—†์ด(์ž‘์—…์ด ์ชผ๊ฐœ์ง€์ง€ ์•Š์Œ) ํ•œ ๋ฒˆ์— ์ด๋ฃจ์–ด์ ธ์•ผ ํ•œ๋‹ค. ์ด๊ฒƒ์„ ๋” ์ด์ƒ ์ชผ๊ฐœ์งˆ ์ˆ˜ ์—†๋Š” ์›์ž์— ๋น—๋Œ€์–ด ํ‘œํ˜„ํ•œ ๊ฒƒ์ด๋‹ค.
  • Consistency(์ผ๊ด€์„ฑ): ํŠธ๋žœ์žญ์…˜์€ ์ผ๊ด€์„ฑ ์žˆ๋Š” ๊ฒฐ๊ณผ๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค.
  • Isolation(๊ฒฉ๋ฆฌ์„ฑ): ๋™์‹œ์— ์‹คํ–‰๋˜๋Š” ํŠธ๋žœ์žญ์…˜์€ ์„œ๋กœ์—๊ฒŒ ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๊ณ  ๊ฒฉ๋ฆฌ๋˜์–ด ์žˆ๋‹ค.
  • Durability(์ง€์†์„ฑ): ํŠธ๋žœ์žญ์…˜์„ ์„ฑ๊ณต์ ์œผ๋กœ ์ˆ˜ํ–‰ํ–ˆ์„ ๋•Œ ๊ฒฐ๊ณผ๋Š” ํ•ญ์ƒ ์ €์žฅ๋ผ์•ผ ํ•œ๋‹ค.

@Transactional ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ๋ณ€๊ฒฝ ํ•  ์ˆ˜ ์žˆ๋Š” ์„ค์ •๋“ค์€ ๋งŽ์ง€๋งŒ Pet Clinic์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ readOnly ๊ด€๋ จ ์„ค์ •๋ฟ์ด๋‹ค. readOnly ์„ค์ •์„ true๋กœ ํ•  ๊ฒฝ์šฐ read ์™ธ์˜ insert, update, delete ์ž‘์—… ์‹คํ–‰ ์‹œ ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค.

@Cacheable ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด ์บ์‹œ ์„ค์ •์„ ํ•œ๋‹ค. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์ฝ์–ด์˜ค๋Š” ๊ฐ’์ด ๋ณ€ํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ(์ˆ˜์ •์ด ์•ˆ๋  ๊ฒฝ์šฐ) ์บ์‹œ ์„ค์ •์„ ํ•˜๋Š” ๊ฒƒ์ด ์œ ๋ฆฌํ•˜๋‹ค.

๐Ÿถ Pet Clinic์˜ Repository

Pet Clinic์—๋Š” Repository๊ฐ€ ๋‘ ๊ฐœ ์กด์žฌํ•œ๋‹ค. ํ•˜๋‚˜๋Š” owner์— ๊ด€ํ•œ Repository์ด๊ณ , ๋‚˜๋จธ์ง€ ํ•˜๋‚˜๋Š” veterinarian์— ๊ด€ํ•œ Repository๋‹ค.

๐Ÿ‘ผ๐Ÿป OwnerRepository

OwnerRepository๋Š” owner๋Š” ๋ฌผ๋ก  owner๊ฐ€ ๊ฐ€์ง„ pet๋“ค๊ณผ ๊ฐ pet์˜ ๋ฐฉ๋ฌธ ๊ธฐ๋ก ๊ด€๋ จ ์ฟผ๋ฆฌ๋ฅผ ๋ชจ๋‘ ์ฒ˜๋ฆฌํ•œ๋‹ค. OwnerRepository์˜ ๋ฉ”์„œ๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

- findPetType()

@Query("SELECT ptype FROM PetType ptype ORDER BY ptype.name")
@Transactional(readOnly = true)
List<PetType> findPetTypes();

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ PetType๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค. ๊ฒฐ๊ณผ๋Š” List<PetType> ํƒ€์ž…์œผ๋กœ ๋ฐ˜ํ™˜๋œ๋‹ค. @Query ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด ์ง์ ‘ ์ฟผ๋ฆฌ๋ฌธ์„ ์ž‘์„ฑํ•˜๊ณ  ์žˆ๋‹ค. @Transactional์— readOnly ์†์„ฑ์„ ์ฃผ์–ด ์ฝ๊ธฐ ์ „์šฉ์œผ๋กœ ์„ค์ •ํ•œ๋‹ค.

- findByLastName(lastName, pageable)

@Query("SELECT DISTINCT owner FROM Owner owner left join  owner.pets 
										WHERE owner.lastName LIKE :lastName% ")
@Transactional(readOnly = true)
Page<Owner> findByLastName(@Param("lastName") String lastName, Pageable pageable);

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ lastName์ด ์ผ์น˜ํ•˜๋Š” owner๋ฅผ ์ฐพ๋Š”๋‹ค. ๊ฒฐ๊ณผ๋Š” Page<Owner> ํƒ€์ž…์œผ๋กœ ๋ฐ˜ํ™˜๋œ๋‹ค. ๋ชฉ๋ก ํŽ˜์ด์ง€ ๋ Œ๋”๋ง์— ์‚ฌ์šฉ๋œ๋‹ค. @Query ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด ์ง์ ‘ ์ฟผ๋ฆฌ๋ฌธ์„ ์ž‘์„ฑํ•˜๊ณ  ์žˆ๋‹ค. @Transactional์— readOnly ์†์„ฑ์„ ์ฃผ์–ด ์ฝ๊ธฐ ์ „์šฉ์œผ๋กœ ์„ค์ •ํ•œ๋‹ค.

- findById(id)

@Query("SELECT owner FROM Owner owner left join fetch owner.pets WHERE owner.id =:id")
@Transactional(readOnly = true)
Owner findById(@Param("id") Integer id);

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ id๊ฐ€ ์ผ์น˜ํ•˜๋Š” Owner๋ฅผ ์ฐพ๋Š”๋‹ค. ๊ฒฐ๊ณผ๋Š” Owner ํƒ€์ž…์œผ๋กœ ๋ฐ˜ํ™˜๋œ๋‹ค. @Query ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด ์ง์ ‘ ์ฟผ๋ฆฌ๋ฌธ์„ ์ž‘์„ฑํ•˜๊ณ  ์žˆ๋‹ค. @Transactional์— readOnly ์†์„ฑ์„ ์ฃผ์–ด ์ฝ๊ธฐ ์ „์šฉ์œผ๋กœ ์„ค์ •ํ•œ๋‹ค.

- save(owner)

void save(Owner owner);

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— owner๋ฅผ ์ €์žฅํ•œ๋‹ค. ์ฟผ๋ฆฌ๋ฌธ์˜ ์ƒ์„ฑ์„ JPA์—๊ฒŒ ๋งก๊ธฐ๊ณ  ์žˆ๋‹ค.

- findAll(pageable)

@Query("SELECT owner FROM Owner owner")
@Transactional(readOnly = true)
Page<Owner> findAll(Pageable pageable);

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ๋ชจ๋“  Owner๋ฅผ ์ฐพ๋Š”๋‹ค. ๊ฒฐ๊ณผ๋Š” Page<Owner> ํƒ€์ž…์œผ๋กœ ๋ฐ˜ํ™˜๋œ๋‹ค. ๋ชฉ๋ก ํŽ˜์ด์ง€ ๋ Œ๋”๋ง์— ์‚ฌ์šฉ๋œ๋‹ค. @Query ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด ์ง์ ‘ ์ฟผ๋ฆฌ๋ฌธ์„ ์ž‘์„ฑํ•˜๊ณ  ์žˆ๋‹ค. @Transactional์— readOnly ์†์„ฑ์„ ์ฃผ์–ด ์ฝ๊ธฐ ์ „์šฉ์œผ๋กœ ์„ค์ •ํ•œ๋‹ค.

๐Ÿง‘๐Ÿปโ€โš•๏ธ VetRepository

VetRepository๋Š” Veterinarian์˜ ๋ชฉ๋ก์„ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋ฉ”์„œ๋“œ๋งŒ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. OwnerRepository์— ๋น„ํ•ด ๋ฉ”์„œ๋“œ์˜ ์ˆ˜๊ฐ€ ์ ๋‹ค. ๋‘ ๊ฐ€์ง€๋ฐ–์— ์—†๋‹ค. ์ด ๋‘˜์˜ ์ฐจ์ด์ ์€ ํŒŒ๋ผ๋ฏธํ„ฐ์˜ ์œ ๋ฌด์™€ ๊ทธ์— ๋”ฐ๋ฅธ ๋ฐ˜ํ™˜ ํƒ€์ž…์ด ๋‹ค๋ฅด๋‹ค๋Š” ์ ์ด๋‹ค.

- findAll()

@Transactional(readOnly = true)
@Cacheable("vets")
Collection<Vet> findAll() throws DataAccessException;

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ๋ชจ๋“  Vet์„ ์ฐพ๋Š”๋‹ค. ๊ฒฐ๊ณผ๋Š” Collection<Vet> ํƒ€์ž…์œผ๋กœ ๋ฐ˜ํ™˜๋œ๋‹ค. @Transactional์— readOnly ์†์„ฑ์„ ์ฃผ์–ด ์ฝ๊ธฐ ์ „์šฉ์œผ๋กœ ์„ค์ •ํ•œ๋‹ค. @Cacheable ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด ์บ์‹œ ์„ค์ •์„ ํ•œ๋‹ค. Pet Clinic์—์„œ Vet์˜ ๋ชฉ๋ก์€ ์ˆ˜์ •ํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์บ์‹œ ์„ค์ •์„ ํ•˜๋Š” ๊ฒƒ์ด ์œ ๋ฆฌํ•˜๋‹ค. (Vet ๋ชฉ๋ก์„ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๊ฒŒ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•˜๋ฉด ์ด ์–ด๋…ธํ…Œ์ด์…˜์€ ์ œ๊ฑฐํ•˜๋Š” ํŽธ์ด ์ข‹๋‹ค.) DataAccessException์ด ๋ฐœ์ƒํ•  ๊ฒฝ์šฐ throw ํ•œ๋‹ค. (๋‹ค๋ฅธ ๋ฉ”์†Œ๋“œ์—๊ฒŒ ์ฒ˜๋ฆฌ ์œ„์ž„)

- findAll(pageable)

@Transactional(readOnly = true)
@Cacheable("vets")
Page<Vet> findAll(Pageable pageable) throws DataAccessException;

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ๋ชจ๋“  Vet์„ ์ฐพ๋Š”๋‹ค. ๊ฒฐ๊ณผ๋Š” Page<Vet> ํƒ€์ž…์œผ๋กœ ๋ฐ˜ํ™˜๋œ๋‹ค. ๋ชฉ๋ก ํŽ˜์ด์ง€ ๋ Œ๋”๋ง์— ์‚ฌ์šฉ๋œ๋‹ค. @Transactional์— readOnly ์†์„ฑ์„ ์ฃผ์–ด ์ฝ๊ธฐ ์ „์šฉ์œผ๋กœ ์„ค์ •ํ•œ๋‹ค. @Cacheable ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด ์บ์‹œ์„ค์ •์„ ํ•œ๋‹ค. DataAccessException์ด ๋ฐœ์ƒํ•  ๊ฒฝ์šฐ throw ํ•œ๋‹ค.

๐Ÿ—’ Repository์˜ naming convention

Repository์˜ ๋ฉ”์„œ๋“œ naming convention์€ ๊ธฐ๋ณธ์ ์œผ๋กœ read ์ž‘์—…์˜ ๊ฒฝ์šฐ findBy{์ฐพ์„๋Œ€์ƒ}(๋Œ€์ƒ ํŠน์ • ์ •๋ณด)์œผ๋กœ ํ•œ๋‹ค. ๋Œ€์ƒ์˜ ๋ชจ๋“  ๋ชฉ๋ก์„ ํ•„์š”๋กœํ•  ๊ฒฝ์šฐ findAll์œผ๋กœ ํ•œ๋‹ค. ๋ฐ์ดํ„ฐ ์ €์žฅ(create, update ๋“ฑ)์˜ ๊ฒฝ์šฐ save(์ €์žฅ ๋Œ€์ƒ)์œผ๋กœ ํ•œ๋‹ค. ์ž์„ธํ•œ ์‚ฌํ•ญ์€ ์•„๋ž˜์˜ ์ฐธ๊ณ  ๋งํฌ๋ฅผ ํ™œ์šฉํ•˜๋ฉด ๋œ๋‹ค.

๐Ÿงฉ ๋งˆ๋ฌด๋ฆฌ

๊ธธ๊ณ  ๊ธธ์—ˆ๋˜ Pet Clinic์˜ ๋ถ„์„์ด ๋๋‚ฌ๋‹ค. ๋ง‰ํŒ์—๋Š” ์ด๊ฑธ ์™œ ํ•˜๊ณ  ์žˆ๋Š”๊ฐ€์— ๋Œ€ํ•œ ํ˜„ํƒ€๊ฐ€ ์™”์ง€๋งŒ, ์–ด์จŒ๋“  ๊ฐ„์— ์ด ๋ถ„์„ํ•œ ๋‚ด์šฉ์„ ํ† ๋Œ€๋กœ ์‹ค์ œ ํ”„๋กœ์ ํŠธ์— ์ ์šฉํ•ด ๋ณด๋Š” ๊ฒƒ์ด ์‹ค๋ ฅ ํ–ฅ์ƒ์„ ์œ„ํ•œ ๊ธธ์ด๊ฒ ์ง€.. ์ผ๋‹จ ๋ญ๋ฅผ ํ•ด์•ผ ํ• ์ง€ ๊ณ ๋ฏผ์ด์ง€๋งŒ ์–ผ๋ฅธ ์ •ํ•ด์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•  ์˜ˆ์ •์ด๋‹ค. ๋๊นŒ์ง€ ํฌ๊ธฐํ•˜์ง€ ์•Š๊ณ  ์ง„ํ–‰ํ•˜๋Š” ๊ฒƒ์ด ๋ชฉํ‘œ๋‹ค..! ํ™”์ดํŒ…~!!

[์ฐธ๊ณ ]

@Transactional ์–ด๋…ธํ…Œ์ด์…˜ ์„ค๋ช… -
https://goddaehee.tistory.com/167
@Cacheable ์–ด๋…ธํ…Œ์ด์…˜ ์„ค๋ช… -
https://velog.io/@bey1548/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%BA%90%EC%8B%9CCacheable-CacheEvict
Repository Methods -
https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/repository/CrudRepository.html

profile
๊ฐœ๋ฐœ์ž์ง€๋ง์ƒ

0๊ฐœ์˜ ๋Œ“๊ธ€