๊ด€๋ฆฌ ๋ฉ”๋‰ด

DOing

[Spring] Spring Data JPA ์ดํ•ดํ•˜๊ธฐ (feat ORM, JPA) ๋ณธ๋ฌธ

Spring

[Spring] Spring Data JPA ์ดํ•ดํ•˜๊ธฐ (feat ORM, JPA)

mangdo 2021. 7. 4. 11:09

 

๐ŸŒฑ ORM ์ด๋ž€?

  ORM ์ด๋ž€ Object-Relational Mapping ์˜ ์•ฝ์ž๋กœ, ์ด๋ฆ„ ๊ทธ๋Œ€๋กœ ๊ฐ์ฒด(Object)์™€ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ(Relational data) ๋ฅผ ๋งคํ•‘ํ•˜๊ธฐ ์œ„ํ•œ ๊ธฐ์ˆ ์ด๋‹ค. ์ด๋Ÿฌํ•œ ๋งคํ•‘์ด ํ•„์š”ํ•œ ์ด์œ ๋Š” ๊ฐ์ฒด ์ง€ํ–ฅ ์–ธ์–ด๊ณผ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์‚ฌ์ด์˜ ํŒจ๋Ÿฌ๋‹ค์ž„ ๋ถˆ์ผ์น˜๊ฐ€ ์žˆ๊ธฐ๋•Œ๋ฌธ์ด๋‹ค.  ์ด ๋‘˜ ๊ฐ„์˜ ํŒจ๋Ÿฌ๋‹ค์ž„ ๋ถˆ์ผ์น˜ ๋•Œ๋ฌธ์— ๊ฐœ๋ฐœ์ž๋Š” ๋” ๋งŽ์€ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•˜๋ฉฐ, ์ด๋Š” ๋ฐ˜๋ณต์ ์ด๊ณ  ์‹ค์ˆ˜ํ•˜๊ธฐ ์‰ฌ์šด ์ž‘์—…์ด ๋œ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ๊ฐœ๋ฐœ์ž๋Š” ๊ฐ์ฒด์ง€ํ–ฅ์ ์ธ ์„ค๊ณ„์— ์ง‘์ค‘ํ•  ์ˆ˜ ์—†๊ฒŒ ๋œ๋‹ค. ORM์ด ๋ฐ”๋กœ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ด ์ค€๋‹ค. 

https://medium.com/@emccul13/object-relational-mapping-9d84807f5536

 

๐ŸŒฑ ํŒจ๋Ÿฌ๋‹ค์ž„ ๋ถˆ์ผ์น˜

 ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ๊ณผ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์‚ฌ์ด์˜ ๋ฐ์ดํ„ฐ ํ‘œํ˜„ ๋ฐฉ์‹์ด ๋‹ฌ๋ผ์„œ ์ƒ๊ธฐ๋Š” ๋ฌธ์ œ๋ฅผ ํŒจ๋Ÿฌ๋‹ค์ž„ ๋ถˆ์ผ์น˜๋ผ๊ณ  ํ•œ๋‹ค. ํŒจ๋Ÿฌ๋‹ค์ž„ ๋ถˆ์ผ์น˜๊ฐ€ ์ผ์–ด๋‚˜๋Š” ์ด์œ ๋Š” ์• ์ดˆ์— ์ด๋“ค์˜ ๋ชฉํ‘œ์™€ ๋™์ž‘ ๋ฐฉ์‹์ด ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

  • ๊ฐ์ฒด ์ง€ํ–ฅ
    • ํ•„๋“œ์™€ ๋ฉ”์„œ๋“œ ๋“ฑ์„ ๋ฌถ์–ด์„œ ๊ฐ์ฒด๋กœ ์ž˜ ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋ชฉํ‘œ
    • ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์€ ์ถ”์ƒํ™”, ์บก์Šํ™”, ์ •๋ณด์€๋‹‰, ์ƒ์†, ๋‹คํ˜•์„ฑ ๋“ฑ ์‹œ์Šคํ…œ์˜ ๋ณต์žก์„ฑ์„ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋Š” ๋‹ค์–‘ํ•œ ์žฅ์น˜๋“ค์„ ์ œ๊ณตํ•œ๋‹ค.
  • ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค
    • ๋ฐ์ดํ„ฐ๋ฅผ ์ž˜ ์ •๊ทœํ™”ํ•ด์„œ ๋ณด๊ด€ํ•˜๋Š” ๊ฒƒ์ด ๋ชฉํ‘œ

 

๐ŸŒฑ JPA

  JPA๋Š” Java Persistence API์˜ ์•ฝ์ž๋กœ, ์ž๋ฐ” ORM ๊ธฐ์ˆ ์— ๋Œ€ํ•œ API ํ‘œ์ค€ ๋ช…์„ธ์ด๋‹ค. ์ฆ‰, ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋ชจ์Œ์ด๋‹ค. ์ด๋Ÿฌํ•œ JPA ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•œ ๋Œ€ํ‘œ์ ์ธ ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ํ•˜์ด๋ฒ„๋„ค์ดํŠธ(Hibernate)์ด๋‹ค.JPA๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ JDBC ์‚ฌ์ด์—์„œ ๋™์ž‘ํ•œ๋‹ค. ๊ฐœ๋ฐœ์ž๊ฐ€ JPA๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, JPA ๋‚ด๋ถ€์—์„œ JDBC API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ SQL์„ ํ˜ธ์ถœํ•˜์—ฌ DB์™€ ํ†ต์‹ ํ•œ๋‹ค. ์ฆ‰, ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ JDBC API๋ฅผ ์“ธ ํ•„์š”๊ฐ€ ์—†๋‹ค.

 

๐ŸŒฑ Hibernate

 JPA๋ฅผ ๊ตฌํ˜„ํ•œ ํ”„๋ ˆ์ž„์›Œํฌ ์ค‘ ์‚ฌ์‹ค์ƒ ํ‘œ์ค€์ด๋‹ค. ์˜คํ”ˆ์†Œ์Šค ์†Œํ”„ํŠธ์›จ์–ด์ด๋‹ค. ์—ฌ๊ธฐ์„œ ์ฃผ๋ชฉํ•ด์•ผํ•  ์ ์€ JPA๋Š” ๊ธฐ์ˆ  ์ŠคํŽ™์ด๊ณ  ํ•˜์ด๋ฒ„๋„ค์ดํŠธ๋Š” ์ด ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜์—ฌ ๊ณต๊ธ‰ํ•ด์ฃผ๋Š” ์—ญํ• ์ด๋‹ค.

 

๐ŸŒฑ Spring Data JPA

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

 Spring Data JPA๋Š” JPA Provider์ด ์•„๋‹ˆ๋‹ค. ๋‹จ์ง€ ๋ฐ์ดํ„ฐ ๊ณ„์ธต์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ๋ป”ํ•œ ์ฝ”๋“œ๋“ค์˜ ์‚ฌ์šฉ์„ ์ค„์—ฌ์ฃผ๋„๋ก ํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค์ด๋‹ค. ์—ฌ๊ธฐ์„œ ๋ฐ˜๋“œ์‹œ ๊ธฐ์–ตํ•ด์•ผํ•  ์ ์€ Spring Data JPA๋Š” ํ•ญ์ƒ ํ•˜์ด๋ฒ„๋„ค์ดํŠธ์™€ ๊ฐ™์€ JPA provider๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

์ถœ์ฒ˜ : ์Šคํ”„๋ง๋ถ€ํŠธ์™€ aws๋กœ ํ˜ผ์ž ๊ตฌํ˜„ํ•˜๋Š” ์›น์„œ๋น„์Šค(์ด๋™์šฑ ์ €)

 

๐ŸŒฑ Spring Data JPA ์˜ˆ์ œ ์ฝ”๋“œ

* Entity ์ƒ์„ฑ

@Entity
public class Product extends Timestamped {
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Id
    private Long id;
    private Long userId;
    private String title;
    private String image;
    private String link;
    private int lprice;
    private int myprice;
}

* Spring Data JPA) Repository ์ƒ์„ฑ

public interface ProductRepository extends JpaRepository<Product, Long> {
}

 

* Spring Data JPA) Repository ๊ธฐ๋ณธ ์ œ๊ณต ๊ธฐ๋Šฅ

// 1. ์ƒํ’ˆ ์ƒ์„ฑ
Product product = new Product(...);
productRepository.save(product);

// 2. ์ƒํ’ˆ ์ „์ฒด ์กฐํšŒ
List<Product> products = productRepository.findAll();

// 3. ์ƒํ’ˆ ์ „์ฒด ๊ฐœ์ˆ˜ ์กฐํšŒ
long count = productRepository.count();

// 4. ์ƒํ’ˆ ์‚ญ์ œ
productRepository.delete(product);

 

* Spring Data JPA) ์ถ”๊ฐ€๊ธฐ๋Šฅ์€ interface ๋งŒ ์„ ์–ธํ•ด ์ฃผ๋ฉด, ๊ตฌํ˜„์€ Spring Data JPA ๊ฐ€ ๋Œ€์‹ ํ•œ๋‹ค.

public interface ProductRepository extends JpaRepository<Product, Long> {
  // (1) ํšŒ์› ID ๋กœ ๋“ฑ๋ก๋œ ์ƒํ’ˆ๋“ค ์กฐํšŒ
  List<Product> findAllByUserId(Long userId);

  // (2) ์ƒํ’ˆ๋ช…์ด title ์ธ ๊ด€์‹ฌ์ƒํ’ˆ 1๊ฐœ ์กฐํšŒ
  Product findByTitle(String title);

  // (3) ์ƒํ’ˆ๋ช…์— word ๊ฐ€ ํฌํ•จ๋œ ๋ชจ๋“  ์ƒํ’ˆ๋“ค ์กฐํšŒ
  List<Product> findAllByTitleContaining(String word);

  // (4) ์ตœ์ €๊ฐ€๊ฐ€ fromPrice ~ toPrice ์ธ ๋ชจ๋“  ์ƒํ’ˆ๋“ค์„ ์กฐํšŒ
  List<Product> findAllByLpriceBetween(int fromPrice, int toPrice);
}

Spring Data JPA ์ถ”๊ฐ€๊ธฐ๋Šฅ ๊ตฌํ˜„๋ฐฉ๋ฒ•์€ ๊ณต์‹๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•œ๋‹ค.

์ด์™ธ์— ๋ณต์žกํ•œ ์ฟผ๋ฆฌ๋Š” ์ง์ ‘ ์งค ์ˆ˜๋„ ์žˆ๋‹ค.