본문 바로가기
스프링 관련/스프링 따라하기

3. Repository

by 문자메일 2022. 5. 24.

JPA (Hibernate-하이버네이트)

 

QueryMethod (Spring Data JPA 라이브러리 필요)

: 쿼리 메소드는 스프링 Data JPA에서 제공하는 핵심 기능 중 하나로 Repository 인터페이스에 간단한 네이밍 룰을 이용하여 메소드를 작성하면 원하는 쿼리를 실행할 수 있다.

 

JPQL (Spring Data JPA 라이브러리 필요)

 

QueryDsl (별도 QueryDsl 라이브러리 import 필요)

 

 

따라하기

 

1. application.yml 설정정보 복붙하여 업데이트

h2 DB 관련 다양한 편의 설정 + url으로 h2-console 바로 접근할 수 있게 해주는 설정

127.0.0.1:8081/h2-console

 

server:
  port: 8081

spring:
  application:
    name: personal-study
  datasource:
    driver-class-name: org.h2.Driver
    url: jdbc:h2:mem:testdb
  jpa:
    hibernate:
      ddl-auto: create-drop
    show-sql: true
    generate-ddl: true
    defer-datasource-initialization: true
  h2:
    console:
      enabled: true
      settings:
        web-allow-others: true
      path: /h2-console

 

2. entity/TestEntity.java 생성

@Entity - 어노테이션이 붙은 클래스는 DB Table과 Mapping 되는 클래스.

@Data - 롬복 어노테이션 사용하여 getter/setter 적용

@Table - DB Table 이름 지정 

 

@Id - Entity의 기본키(필수)

@GeneratedValue - 기본키 생성 전략 지정

import lombok.Data;

import javax.persistence.*;

@Entity
@Data
@Table(name = "TestEntity")
public class TestEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String name;

    private int age;

}

 

3. repository/TestRepository.java 인터페이스 생성

DB 제어하고싶은 Entity의 인터페이스 레퍼지토리를 생성하고 Spring Data Jpa 라이브러리 상속.

 ( extends JpaRepository<TestEntity // Enitiy 명칭, Long // 해당 Entity의 Key 자료형> )

 

아래 소스에서 Spring Data JPA에서 제공하는 QueryMethod, @Query 어노테이션 활용하여 DB 접근 구현

 

import com.example.personalstudy.entity.TestEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.List;


@Repository
public interface TestRepository extends JpaRepository<TestEntity, Long> {

    // QueryMethod
    TestEntity findByAge(int age);

    // Spring Data JPA @Query 어노테이션 활용 - JPQL 문법 Version
    @Query("select t from TestEntity t where t.age >= :age")
    List<TestEntity> findEntityLargeThanAge(@Param("age") int age);

    // Spring Data JPA @Query 어노테이션 활용 - Native SQL 문법 Version
    @Query(value = "select * from TEST_ENTITY where age >= :age", nativeQuery = true)
    List<TestEntity> findEntityLargeThanAgeNativeQuery(@Param("age") int age);

}

 

 

4. 기존 TestEntityController.java 업데이트

URL 실행 순서

1. H2 DB에 TestEntity 값 10개 생성하여 저장 - http://127.0.0.1:8081/test-entity/save-entity

2. QueryMetod 활용하여 age가 8인 엔티티 값 1개 DB에서 읽어서 응답 - http://127.0.0.1:8081/test-entity/8

3. @Query + JPQL 문법 활용하여 age가 5 이상인 엔티티 값들 DB에서 읽어서 응답 - http://127.0.0.1:8081/test-entity/jpql/5

4. @Query + Native SQL 문법 활용하여 age가 5 이상인 엔티티 값들 DB에서 읽어서 응답 - http://127.0.0.1:8081/test-entity/jpql/5

import com.example.personalstudy.entity.TestEntity;
import com.example.personalstudy.repository.TestRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/test-entity")
public class TestEntityController {

    private final TestRepository testRepository;

    @Autowired
    TestEntityController(TestRepository testRepository){
        this.testRepository = testRepository;
    }

    @GetMapping(value = "save-entity")
    public String saveTenEntity(){
        for (int i=1;i<=10;i++){
            TestEntity testEntity = new TestEntity();
            testEntity.setAge(i+1);
            testEntity.setName("test"+i);

            testRepository.save(testEntity);
        }
        return "save entity success";
    }


    @GetMapping(value = "/{age}")
    public ResponseEntity<TestEntity> findEntity(@PathVariable int age){
        TestEntity testEntity = testRepository.findByAge(age);
        return ResponseEntity.ok(testEntity);
    }

    @GetMapping(value = "/jpql/{age}")
    public ResponseEntity<List<TestEntity>> findEntityJpql(@PathVariable int age){
        List<TestEntity> testEntityList = testRepository.findEntityLargeThanAge(age);
        return ResponseEntity.ok(testEntityList);
    }

    @GetMapping(value = "/native/{age}")
    public ResponseEntity<List<TestEntity>> findEntityNative(@PathVariable int age){
        List<TestEntity> testEntityList = testRepository.findEntityLargeThanAgeNativeQuery(age);
        return ResponseEntity.ok(testEntityList);
    }
}

 

 

 

※ 아래 코드는 위 예제와 관계없는 부분으로 ResponseEntity<Generic> 사용하여 어떻게 return 하는지 참고하기 위하여 기록해놓음

@GetMapping("/users/{userId}")
public ResponseEntity<ResponseUser> getUser(@PathVariable("userId") String userId){
    UserDto userDto = userService.getUserByUserId(userId);

    ResponseUser returnValue = new ModelMapper().map(userDto, ResponseUser.class);

    return ResponseEntity.status(HttpStatus.OK).body(returnValue);
}

댓글