์ด์ ๊ธ์์ ์ ๋ฆฌํ๋ฏ Repository๋ Spring์์ ์ ๊ณตํ๋ ๋ชจ๋์ธ Spring Data Jpa์ ์ธํฐํ์ด์ค๋ค. ๊ฐ๋ฐ์๋ ์ด Repository ์ธํฐํ์ด์ค๋ฅผ ์์๋ฐ์ ๋ฉ์๋ ์ด๋ฆ๋ง ์ ์์ฑํ๋ฉด JPA๊ฐ ์ด๋ฅผ ํ ๋๋ก ์ฟผ๋ฆฌ๋ฌธ์ ๋ง๋ค์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ ์ ์ํํ๋ค.
์ฟผ๋ฆฌ๋ฌธ์ด ๋ณต์กํ๊ฑฐ๋ JPA๊ฐ ์๋ ์์ฑํ๋ ์ฟผ๋ฆฌ๋ฌธ๊ณผ ๋ค๋ฅธ ์ฟผ๋ฆฌ๋ฌธ์ ์ฌ์ฉํ๊ณ ์ถ์ ๊ฒฝ์ฐ @Query ์ด๋ ธํ ์ด์ ์ ํตํด ์ฟผ๋ฆฌ๋ฌธ์ ์ง์ ์์ฑํ๋ค. ๋ฉ์๋ ์ด๋ฆ ์์ ์ถ๊ฐํ๋ฉด ๋๋ค.
@Transactional ์ด๋ ธํ ์ด์ ์ ํตํด ACID ๊ด๋ จ ์ค์ ์ ๋ณ๊ฒฝํ ์ ์๋ค. ์ฌ๊ธฐ์ ACID๋ Atomicity, Consistency, Isolation, Durability์ ์ ๊ธ์๋ฅผ ๋ด ๊ฒ์ผ๋ก ์์์ฑ, ์ผ๊ด์ฑ, ๊ฒฉ๋ฆฌ์ฑ, ์ง์์ฑ์ ๋ปํ๋ค. ๋ ์์ธํ๊ฒ ์ค๋ช ํ์๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
@Transactional ์ด๋ ธํ ์ด์ ์ผ๋ก ๋ณ๊ฒฝ ํ ์ ์๋ ์ค์ ๋ค์ ๋ง์ง๋ง Pet Clinic์์ ์ฌ์ฉํ๋ ๊ฒ์ readOnly ๊ด๋ จ ์ค์ ๋ฟ์ด๋ค. readOnly ์ค์ ์ true๋ก ํ ๊ฒฝ์ฐ read ์ธ์ insert, update, delete ์์ ์คํ ์ ์์ธ๋ฅผ ๋ฐ์์ํจ๋ค.
@Cacheable ์ด๋ ธํ ์ด์ ์ ํตํด ์บ์ ์ค์ ์ ํ๋ค. ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ฝ์ด์ค๋ ๊ฐ์ด ๋ณํ์ง ์์ ๊ฒฝ์ฐ(์์ ์ด ์๋ ๊ฒฝ์ฐ) ์บ์ ์ค์ ์ ํ๋ ๊ฒ์ด ์ ๋ฆฌํ๋ค.
Pet Clinic์๋ Repository๊ฐ ๋ ๊ฐ ์กด์ฌํ๋ค. ํ๋๋ owner์ ๊ดํ Repository์ด๊ณ , ๋๋จธ์ง ํ๋๋ veterinarian์ ๊ดํ Repository๋ค.
OwnerRepository๋ owner๋ ๋ฌผ๋ก owner๊ฐ ๊ฐ์ง pet๋ค๊ณผ ๊ฐ pet์ ๋ฐฉ๋ฌธ ๊ธฐ๋ก ๊ด๋ จ ์ฟผ๋ฆฌ๋ฅผ ๋ชจ๋ ์ฒ๋ฆฌํ๋ค. OwnerRepository์ ๋ฉ์๋๋ ๋ค์๊ณผ ๊ฐ๋ค.
@Query("SELECT ptype FROM PetType ptype ORDER BY ptype.name")
@Transactional(readOnly = true)
List<PetType> findPetTypes();
๋ฐ์ดํฐ๋ฒ ์ด์ค์์ PetType๋ฅผ ๊ฐ์ ธ์จ๋ค. ๊ฒฐ๊ณผ๋ List<PetType> ํ์ ์ผ๋ก ๋ฐํ๋๋ค. @Query ์ด๋ ธํ ์ด์ ์ ํตํด ์ง์ ์ฟผ๋ฆฌ๋ฌธ์ ์์ฑํ๊ณ ์๋ค. @Transactional์ readOnly ์์ฑ์ ์ฃผ์ด ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ์ค์ ํ๋ค.
@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 ์์ฑ์ ์ฃผ์ด ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ์ค์ ํ๋ค.
@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 ์์ฑ์ ์ฃผ์ด ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ์ค์ ํ๋ค.
void save(Owner owner);
๋ฐ์ดํฐ๋ฒ ์ด์ค์ owner๋ฅผ ์ ์ฅํ๋ค. ์ฟผ๋ฆฌ๋ฌธ์ ์์ฑ์ JPA์๊ฒ ๋งก๊ธฐ๊ณ ์๋ค.
@Query("SELECT owner FROM Owner owner")
@Transactional(readOnly = true)
Page<Owner> findAll(Pageable pageable);
๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ๋ชจ๋ Owner๋ฅผ ์ฐพ๋๋ค. ๊ฒฐ๊ณผ๋ Page<Owner> ํ์ ์ผ๋ก ๋ฐํ๋๋ค. ๋ชฉ๋ก ํ์ด์ง ๋ ๋๋ง์ ์ฌ์ฉ๋๋ค. @Query ์ด๋ ธํ ์ด์ ์ ํตํด ์ง์ ์ฟผ๋ฆฌ๋ฌธ์ ์์ฑํ๊ณ ์๋ค. @Transactional์ readOnly ์์ฑ์ ์ฃผ์ด ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ์ค์ ํ๋ค.
VetRepository๋ Veterinarian์ ๋ชฉ๋ก์ ๋ถ๋ฌ์ค๋ ๋ฉ์๋๋ง์ ๊ฐ์ง๊ณ ์๋ค. OwnerRepository์ ๋นํด ๋ฉ์๋์ ์๊ฐ ์ ๋ค. ๋ ๊ฐ์ง๋ฐ์ ์๋ค. ์ด ๋์ ์ฐจ์ด์ ์ ํ๋ผ๋ฏธํฐ์ ์ ๋ฌด์ ๊ทธ์ ๋ฐ๋ฅธ ๋ฐํ ํ์ ์ด ๋ค๋ฅด๋ค๋ ์ ์ด๋ค.
@Transactional(readOnly = true)
@Cacheable("vets")
Collection<Vet> findAll() throws DataAccessException;
๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ๋ชจ๋ Vet์ ์ฐพ๋๋ค. ๊ฒฐ๊ณผ๋ Collection<Vet> ํ์ ์ผ๋ก ๋ฐํ๋๋ค. @Transactional์ readOnly ์์ฑ์ ์ฃผ์ด ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ์ค์ ํ๋ค. @Cacheable ์ด๋ ธํ ์ด์ ์ ํตํด ์บ์ ์ค์ ์ ํ๋ค. Pet Clinic์์ Vet์ ๋ชฉ๋ก์ ์์ ํ ์ ์๊ธฐ ๋๋ฌธ์ ์บ์ ์ค์ ์ ํ๋ ๊ฒ์ด ์ ๋ฆฌํ๋ค. (Vet ๋ชฉ๋ก์ ๋ฐ๊ฟ ์ ์๊ฒ ์ฝ๋๋ฅผ ์์ ํ๋ฉด ์ด ์ด๋ ธํ ์ด์ ์ ์ ๊ฑฐํ๋ ํธ์ด ์ข๋ค.) DataAccessException์ด ๋ฐ์ํ ๊ฒฝ์ฐ throw ํ๋ค. (๋ค๋ฅธ ๋ฉ์๋์๊ฒ ์ฒ๋ฆฌ ์์)
@Transactional(readOnly = true)
@Cacheable("vets")
Page<Vet> findAll(Pageable pageable) throws DataAccessException;
๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ๋ชจ๋ Vet์ ์ฐพ๋๋ค. ๊ฒฐ๊ณผ๋ Page<Vet> ํ์ ์ผ๋ก ๋ฐํ๋๋ค. ๋ชฉ๋ก ํ์ด์ง ๋ ๋๋ง์ ์ฌ์ฉ๋๋ค. @Transactional์ readOnly ์์ฑ์ ์ฃผ์ด ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ์ค์ ํ๋ค. @Cacheable ์ด๋ ธํ ์ด์ ์ ํตํด ์บ์์ค์ ์ ํ๋ค. DataAccessException์ด ๋ฐ์ํ ๊ฒฝ์ฐ throw ํ๋ค.
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