๐Ÿ’ป Web

[SpringBoot] JpaRepository ์ƒ์„ฑ๊ณผ ๋ฐ์ดํ„ฐ ์กฐํšŒํ•˜๊ธฐ๐Ÿ”

ji_wonna 2022. 8. 1. 21:08

JpaRepository ์ƒ์„ฑํ•˜๊ธฐ

Repository๋ž€?

entity์— ์˜ํ•ด ์ƒ์„ฑ๋œ dbํ…Œ์ด๋ธ”์— ์ ‘๊ทผํ•˜๋Š” ํ•จ์ˆ˜(ex: findAll, save ๋“ฑ)๋“ค์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ์ธํ„ฐํŽ˜์ด์Šค์ด๋‹ค. CRUD๋ฅผ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ• ์ง€ ์ •์˜ํ•˜๋Š” ๊ณ„์ธต์ด๋‹ค.

 

 

PlaceRepository ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

package com.goingto.back;

import org.springframework.data.jpa.repository.JpaRepository;
public interface PlaceRepository extends JpaRepository<Place, Integer>{

}

๋ฆฌํฌ์ง€ํ„ฐ๋ฆฌ๋กœ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด JpaRepository ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ƒ์†ํ–ˆ๋‹ค.

์ƒ์†ํ•  ๋•Œ๋Š” ์ œ๋„ค๋ฆญ์Šค ํƒ€์ž…์œผ๋กœ ์—”ํ‹ฐํ‹ฐ์˜ ํƒ€์ž…๊ณผ ํ•ด๋‹น ์—”ํ‹ฐํ‹ฐ์˜ PK ์†์„ฑ ํƒ€์ž…์„ ์ง€์ •ํ•ด์•ผ ํ•œ๋‹ค.

Place ์—”ํ‹ฐํ‹ฐ๋Š” Integer(id ๊ฐ’) ์†์„ฑ์˜ PK ํƒ€์ž…์„ ๊ฐ€์กŒ๊ธฐ ๋•Œ๋ฌธ์— <Place, Integer>๋ผ๊ณ  ์ž‘์„ฑํ–ˆ๋‹ค.

 

 

์ž‘์„ฑํ•œ Repository๋ฅผ ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์œ„ํ•ด JUnit ๊ธฐ๋ฐ˜์˜ ํ…Œ์ŠคํŠธ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค.

src/test/java/com/goingto/back/BackApplicationsTests.java ํŒŒ์ผ์— ํ…Œ์ŠคํŠธํ•˜๊ณ  ์‹ถ์€ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์ค€๋‹ค.

package com.goingto.back;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.beans.factory.annotation.Autowired;;

@SpringBootTest
class BackApplicationTests {

    @Autowired
    private PlaceRepository placeRepository;

    @Test
    void testJpa() {
        Place p = new Place();
        p.setName("์•„์ด์Šฌ๋ž€๋“œ");
        p.setSeason("๋ด„");
        p.setBudget(500);
        p.setIsDomestic(false);
        p.setPrefer("ํœด์–‘");
        this.placeRepository.save(p);
    }
}

์œ„ ์ฝ”๋“œ๋Š” Place ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์—ฌ Setter๋กœ ์†์„ฑ์„ ์ง€์ •ํ•œ ํ›„ ์ €์žฅํ•œ๋‹ค.

 

@Autowired๋Š” ์Šคํ”„๋ง์˜ DI(Dependency Injection) ๊ธฐ๋Šฅ์œผ๋กœ placeRepository ๊ฐ์ฒด๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•ด์ค€๋‹ค.

์‹ค์ œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ์—๋Š” ์ˆœํ™˜์ฐธ์กฐ์™€ ๊ฐ™์€ ๋ฌธ์ œ๋กœ ์ƒ์„ฑ์ž ํ˜น์€ Setter๋ฅผ ํ†ตํ•œ ๊ฐ์ฒด ์ƒ์„ฑ์ด ๊ถŒ์žฅ๋œ๋‹ค. ํ•˜์ง€๋งŒ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์˜ ๊ฒฝ์šฐ์—๋Š” ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•œ ๊ฐ์ฒด ์ฃผ์ž…์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— @Autowired๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค.

 


 

๋ฐ์ดํ„ฐ ์กฐํšŒํ•˜๊ธฐ

findAll() : ๋ชจ๋“  ๋ฐ์ดํ„ฐ ์กฐํšŒ

package com.goingto.back;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.List;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.beans.factory.annotation.Autowired;;

@SpringBootTest
class BackApplicationTests {

    @Autowired
    private PlaceRepository placeRepository;

    @Test
    void testJpa() {
        List<Place> all = this.placeRepository.findAll();
        assertEquals(3, all.size());//db์‚ฌ์ด์ฆˆ๊ฐ€ 3์ธ์ง€
    }
}

assertEquals(๊ธฐ๋Œ“๊ฐ’, ์‹ค์ œ๊ฐ’)์€ ๊ธฐ๋Œ“๊ฐ’๊ณผ ์‹ค์ œ๊ฐ’์ด ๋™์ผํ•œ์ง€ ์กฐ์‚ฌํ•œ๋‹ค. ๋งŒ์•ฝ ๋™์ผํ•˜์ง€ ์•Š๋‹ค๋ฉด test๋Š” ์‹คํŒจ๋กœ ์ฒ˜๋ฆฌ๋œ๋‹ค.

 

findById() : Id ๊ฐ’์œผ๋กœ ๋ฐ์ดํ„ฐ ์กฐํšŒ

ํ•จ์ˆ˜์˜ ๋ฆฌํ„ด ํƒ€์ž…์ด Place๊ฐ€ ์•„๋‹Œ Optional์ด๋ผ๋Š” ์ ์— ์ฃผ์˜ํ•ด์•ผํ•œ๋‹ค.

 

Optional์€ null ์ฒ˜๋ฆฌ๋ฅผ ์œ ์—ฐํ•˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ํด๋ž˜์Šค๋กœ, isPresent()๋กœ null์ด ์•„๋‹Œ์ง€ ํ™•์ธํ•œ ํ›„์— get()์œผ๋กœ ์‹ค์ œ Place ๊ฐ์ฒด๋ฅผ ์–ป์–ด์•ผ ํ•œ๋‹ค.

package com.goingto.back;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.Optional;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.beans.factory.annotation.Autowired;;

@SpringBootTest
class BackApplicationTests {

    @Autowired
    private PlaceRepository placeRepository;

    @Test
    void testJpa() {
        Optional<Place> op = this.placeRepository.findById(2);
        if(op.isPresent()){
            Place p = op.get();
            assertEquals("๋ฒ ํŠธ๋‚จ", p.getName()); 
        }
    }
}

 

findByName(), findBySeason(), findByBudget()...

์œ„์˜ ํ•จ์ˆ˜๋“ค์€ ์—”ํ‹ฐํ‹ฐ์— ํŠน์ •๋œ ์กฐํšŒ ๊ธฐ๋Šฅ์ด๋‹ค. ๋”ฐ๋ผ์„œ PlaceRepository ์ธํ„ฐํŽ˜์ด์Šค์— ์ง์ ‘ ์ž‘์„ฑํ•ด์ค˜์•ผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์ด PlaceRepository.java ํŒŒ์ผ์„ ์ž‘์„ฑํ–ˆ๋‹ค. ๋ฐ˜ํ™˜ ๊ฐ’์ด ์—ฌ๋Ÿฌ ๊ฐœ์ธ ๊ฒฝ์šฐ์—๋Š” ํ•จ์ˆ˜์˜ ๋ฆฌํ„ด ํƒ€์ž…์„ List๋กœ ํ•ด์•ผ ํ•œ๋‹ค.

package com.goingto.back;

import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;

public interface PlaceRepository extends JpaRepository<Place, Integer>{
    List<Place> findByBudget(Integer budget);
    Place findByImg(String img);
    List<Place> findByIsDomestic(Boolean isDomestic);
    Place findByName(String name);
    List<Place> findByPrefer(String prefer);
    List<Place> findByScenery(String scenery);
    List<Place> findBySeason(String season);
}

 

 

์ด์ œ ์ธํ„ฐํŽ˜์ด์Šค์— ์ž‘์„ฑํ•œ ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ์›ํ•˜๋Š” ํŠน์ • ํ…Œ์ด๋ธ” ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋‹ค!

 

๋‚˜๋Š” season ์†์„ฑ์ด "๋ด„"์ธ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ–ˆ๊ณ  ํ…Œ์ŠคํŠธ๋Š” ์•„์ฃผ ์ž˜ ํ†ต๊ณผ๋๋‹ค.๐Ÿ˜€

package com.goingto.back;

import java.util.List;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.beans.factory.annotation.Autowired;;

@SpringBootTest
class BackApplicationTests {

    @Autowired
    private PlaceRepository placeRepository;

    @Test
    void testJpa() {
        List<Place> p= this.placeRepository.findBySeason("๋ด„");
        for (int i=0;i<p.size();i++){
            System.out.println(p.get(i).getName());
        }
    }
}

 

๋งŒ์•ฝ ๋‘ ๊ฐ€์ง€ ์†์„ฑ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด findBy<์†์„ฑ1>And<์†์„ฑ2> ํ•จ์ˆ˜๋ฅผ Repository์— ์ถ”๊ฐ€ํ•˜๋ฉด ๋œ๋‹ค.

 

์ด์™€ ๊ฐ™์ด JpaRepository์˜ ํ•จ์ˆ˜๋ช…์€ ๊ทœ์น™์— ๋งž๊ฒŒ ์ž‘์„ฑํ–ˆ์„ ๋•Œ SQL ๊ตฌ๋ฌธ์˜ where ์กฐ๊ฑด์„ ๊ฒฐ์ •์ง“๋Š” ์—ญํ• ์„ ํ•ด์ค€๋‹ค.

And ์™ธ์—๋„ Or, Between ๋“ฑ์œผ๋กœ ์‰ฝ๊ฒŒ ์›ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

ํ•จ์ˆ˜ ๋ช…์˜ ์ƒ์„ฑ ๊ทœ์น™์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๊ณต์‹๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•˜๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค.

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.query-creation

 

Spring Data JPA - Reference Documentation

Example 109. Using @Transactional at query methods @Transactional(readOnly = true) interface UserRepository extends JpaRepository { List findByLastname(String lastname); @Modifying @Transactional @Query("delete from User u where u.active = false") void del

docs.spring.io