JPA

Java Persistence API์•ฝ์ž๋กœ ๊ฐ์ฒด์™€ RDB๊ฐ„์— ๋งตํ•‘ ์‹œ์ผœ์ฃผ๋Š” ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋ชจ์Œ์ด๋‹ค. ์ฆ‰, ํŠน์ •๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์•„๋‹ˆ๋ผ ๋ช…์„ธ์ด๋‹ค.

Hibernate

JPA์˜ ๊ตฌํ˜„์ฒด๋กœ, ์ธํ„ฐํŽ˜์ด์Šค์ธ JPA๋ฅผ ๊ตฌํ˜„ํ•œ class๊ฐ™์€ ๊ฒƒ.

JPA๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋ฐ˜๋“œ์‹œ Hibernate๋ฅผ ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€ ์—†๊ณ  ๋‹ค๋ฅธ JPA๊ตฌํ˜„์ฒด๋ฅผ ์‚ฌ์šฉํ•ด๋„ ๋˜๋ฉฐ, ์ง์ ‘ JPA๋ฅผ ๊ตฌํ˜„ํ–์„œ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

Spring Data JPA

Spring์—์„œ ์ œ๊ณตํ•˜๋Š” ๋ชจ๋“ˆ ์ค‘ ํ•˜๋‚˜๋กœ ๊ฐœ๋ฐœ์ž๊ฐ€ JPA๋ฅผ ์ข€๋” ํŽธํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ฃผ๊ธฐ ์œ„ํ•ด Repository๋ผ๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณต (JPA๋ฅผ ์ถ”์ƒํ™” ์‹œํ‚จ๊ฒƒ)

Repository์ธํ„ฐํŽ˜์ด์Šค ๊ทœ์น™๋Œ€๋กœ ๋ฉ”์„œ๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด Spring์ด ์•Œ์•„์„œ JPA๋ฅผ ์ด์šฉํ•˜์—ฌ ์ ํ•ฉํ•œ ์ฟผ๋ฆฌ๋ฅผ ๋‚ ๋ฆฌ๋Š” ๊ตฌํ˜„์ฒด๋ฅผ ๋งŒ๋“ค์–ด BEAN์œผ๋กœ ๋“ฑ๋ก ํ•ด์ฃผ๋Š” ๊ฒƒ. (์ •ํ™•ํžˆ๋Š” ๋ฉ”์„œ๋“œ๋ช…๊ฐ€์ง€๊ณ  ์ ํ•ฉํ•œ JPQL์„ ์ƒ์„ฑํ•ด์ค€๋‹ค.)

๊ณตํ†ต ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ตฌํ˜„์ฒด๋Š” SimpleJpaRepository์ด๋‹ค.

๋™์ž‘๊ณผ์ •

์•ฑ๊ณผ JDBC ์‚ฌ์ด์—์„œ ๋™์ž‘ํ•˜๋ฉฐ, JPA๋ฅผ ์‚ฌ์šฉ์‹œ JPA๋‚ด๋ถ€์—์„œ JDBC API๋ฅผ ์‚ฌ์šฉํ•ด DB์™€ ํ†ต์‹ ์„ ํ•œ๋‹ค.

์ธํ„ฐํŽ˜์ด์Šค๋งŒ ๋งŒ๋“ค์–ด๋„ ์‹คํ–‰ํ• ๋•Œ ์ธํ„ฐํŽ˜์ด์Šค๋“ค์„ ์ฐพ์•„์„œ ๊ตฌํ˜„์ฒด๋ฅผ ๋งŒ๋“ค๊ณ  ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•ด์ค€๋‹ค.

์ €์žฅ/์กฐํšŒ ๊ณผ์ •

JPA์—๊ฒŒ ๊ฐ์ฒด๋ฅผ ๋„˜๊ธฐ๋ฉด JPA๋Š” ์—”ํ‹ฐํ‹ฐ๋ฅผ ๋ถ„์„ํ•˜์—ฌ, SQL๋ฌธ์„ ์ƒ์„ฑํ•˜๊ณ  ์ด๋ฅผ JDBC API๊ฐ€ DB์— ๋‚ ๋ฆฌ๊ณ  ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ฒด์— ๋งคํ•‘์‹œํ‚จ๋‹ค.

์žฅ์ 

  • SQL์˜ ์ฝ”๋“œ ๋ฐ˜๋ณต์„ ์ค„์—ฌ์ฃผ๊ณ , CRUD๋ฅผ ๊ฐ„๋‹จํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ์–ด ์ƒ์‚ฐ์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์šฉ์ดํ•˜๋‹ค.

  • ๊ฐ์ฒด์™€ RDB๊ฐ„์˜ ๋ชจ๋ธ๋ง์ด ๋‹ฌ๋ผ ๋ฐœ์ƒํ•˜๋Š” ํŒจ๋Ÿฌ๋‹ค์ž„ ๋ถˆ์ผ์น˜๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

    (๊ฐ์ฒด๋Š” ๋‹จ๋ฐฉํ–ฅ์˜ ์ƒ์†๊ด€๊ณ„์™€ ์ฐธ์กฐ๋ฅผ ํ†ตํ•œ ์—ฐ๊ด€๊ด€๊ณ„๋ฅผ ๊ฐ–๊ณ  RDB๋Š” ์ƒ์†๊ด€๊ณ„๊ฐ€ ์—†์ด ํ…Œ์ด๋ธ”๊ฐ„์˜ ์Šˆํผ-์„œ๋ธŒ ํƒ€์ž…๊ด€๊ณ„์˜ ์–‘๋ฐฉํ–ฅ ์—ฐ๊ด€๊ด€๊ณ„๋ฅผ ๊ฐ–๋Š”๋‹ค.)

  • ๋™์ผํ•œ ํŠธ๋žœ์žญ์…˜ ์•ˆ์—์„œ๋Š” ๊ฐ™์€ ์—”ํ„ฐํ‹ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜์—ฌ ์บ์‹ฑ๊ธฐ๋Šฅ๊ณผ ๋™์ผ์„ฑ์„ ๋ณด์žฅํ•œ๋‹ค.

  • ํŠธ๋žœ์žญ์…˜์„ commitํ• ๋•Œ๊นŒ์ง€ ์“ฐ๊ธฐ ์ง€์—ฐ(๋ฒ„ํผ๋ง)์„ ์ง€์›ํ•˜์—ฌ ํ•œ๋ฒˆ์— SQL๋ฌธ์„ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

  • ๊ฐ์ฒด๊ฐ€ ์‹ค์ œ๋กœ ์‚ฌ์šฉ๋  ๋•Œ ๋กœ๋”ฉํ•˜๋Š” ์ง€์—ฐ ๋กœ๋”ฉ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์‚ฌ์šฉ๋ฒ•

Repository ๋ฐฉ์‹์€ Entity์—์„œ Spring Data JPA์—์„œ ์ œ๊ณตํ•˜๋Š” JpaRepository์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ƒ์†ํ•˜๊ธฐ๋งŒ ํ•ด๋„ ๋˜์–ด, ์ธํ„ฐํŽ˜์ด์Šค์— ๋”ฐ๋กœ @Repository๋ฅผ ์ถ”๊ฐ€ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.

์ƒ์†๋ฐ›์„ ๋•Œ๋Š” JpaRepository<T,ID>์˜ ํ˜•ํƒœ๋กœ Entity์˜ ํด๋ž˜์Šค์™€ ID๊ฐ’์ด ๋“ค์–ด๊ฐ€๊ฒŒ ๋œ๋‹ค.

๊ธฐ๋Šฅ

  • save() : ๋ ˆ์ฝ”๋“œ ์ €์žฅ (INSERT, UPDATE)

  • findOne() : primary key๋กœ ๋ ˆ์ฝ”๋“œ ์ฐพ๊ธฐ

  • findAll() : ์ „์ฒด ๋ ˆ์ฝ”๋“œ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ( sort, pageable )

  • count() : ๋ ˆ์ฝ”๋“œ ๊ฐฏ์ˆ˜

  • delete() : ๋ ˆ์ฝ”๋“œ ์‚ญ์ œ

์œ„์˜ ๊ธฐ๋Šฅ์„ ์ œ์™ธํ•œ ๊ธฐ๋Šฅ์€ ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋ช…๋ช… ๊ทœ์น™์€ Refernece๋ฅผ ์ฐธ์กฐํ•˜์ž.

  • findBy~ : ์ฟผ๋ฆฌ๋ฅผ ์š”์ฒญํ•˜๋Š” ๋ฉ”์„œ๋“œ

  • countBy~ : ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ ๋ ˆ์ฝ”๋“œ ์ˆ˜๋ฅผ ์š”์ฒญํ•˜๋Š” ๋ฉ”์„œ๋“œ

๋ฉ”์„œ๋“œ์˜ ๋ฐ˜ํ™˜ํ˜•์ด Entity๊ฐ์ฒด์ด๋ฉด ํ•˜๋‚˜์˜ ๊ฒฐ๊ณผ, List์ด๋ฉด ๋ชจ๋“  ๊ฐ์ฒด๋ฅผ ์ „๋‹ฌ

JPA NamedQuery

@Entity
@NamedQuery(
  name = "Member.findByUsername",
  query = "select m from Member m where m.username = :username")
public class Member{
  //...
}
<named-query name="Member.findByUsername">
  <query><CDATA[
    select m
    from Member m
    where m.username = :username]>
  </query>
</named-query>

Entity์— ์–ด๋…ธํ…Œ์ด์…˜์ด๋‚˜ xmlํŒŒ์ผ์„ ์ด์šฉํ•ด์„œ ์ •์˜ํ•œ ๋‚ด์šฉ์„ ๊ฐ€์ง€๊ณ  Repository์— ํ•ด๋‹น ์ด๋ฆ„์œผ๋กœ ๋ฉ”์„œ๋“œ๋ฅผ ๋งŒ๋“ค๋ฉด NamedQuery์— ๋งค์นญ์‹œ์ผœ ์ƒ์„ฑํ•ด์ฃผ๊ณ  ๋งŒ์•ฝ NamedQuery๊ฐ€ ์—†๋‹ค๋ฉด ๋ฉ”์„œ๋“œ๋ช…์— ๋งž๋Š” JPQL์„ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•ด์ค€๋‹ค.

@Query

public interface MemberRepository extends JpaRepository<Memeber,Long>{
  @Query("select m from Memeber m where m.username = :username")
  Member findByusername(@Param("username") String username);
}

@Query ์–ด๋…ธํ…Œ์ด์…˜์„ ์ด์šฉํ•ด ์ธํ„ฐํŽ˜์ด์Šค ๋‚ด์—์„œ ์ง์ ‘ JPQL์„ ์ƒ์„ฑํ•  ์ˆ˜๋„ ์žˆ๊ณ , ์˜ต์…˜์œผ๋กœ natvieQuery = true์˜ต์…˜์„ ์ด์šฉํ•˜๋ฉด SQL๋ฌธ์œผ๋กœ ์ž‘์„ฑํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

@Modifying

๋ฒŒํฌ ์ฟผ๋ฆฌ๋ฅผ ๋‚ ๋ฆด ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜์ด๋‹ค.

@Modifying(clearAutomatically = true)
@Query("update Product p set p.price = p.price * 1.1 where p.stockAmount < :stockAmount")
int bulkPriceUp(@Param("stockAmount") String stockAmount);

clearAutomatically์˜ต์…˜์œผ๋กœ ์ฟผ๋ฆฌ ํ›„ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ์ดˆ๊ธฐํ™” ํ•˜๋Š” ์˜ต์…˜์„ ์ค„ ์ˆ˜ ์žˆ๋‹ค.


Reference

https://docs.spring.io/spring-data/jpa/docs/1.10.1.RELEASE/reference/html/#jpa.sample-app.finders.strategies

https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html

Last updated