본문 바로가기
💻 개발/Spring

Repository Interface 계층 살펴보기

by 컴쏘 2023. 7. 20.

JPA를 사용하기 위해서는 build.gradle에 의존성이 추가되어있어야 한다.

build.gradle에 JPA 의존성 확인

만약, 의존성이 추가되어있지 않다면, 추가해주도록 하자.

 

ORM

  • db에서의 table과 Java 객체 간의 연결을 만들어주는 것
  • 여기서 말하는 Java 객체는 Entity이다.
  • 객체를 Entity로 선언하기 위해서는 @Entity를 추가하면 된다.

User class에 @Entity 선언하기

@Entity 추가

  • @Entity만 선언하게 되면 User에 빨간 밑줄이 그어진다.
    • 이는 Entity에는 PK가 반드시 필요하기 때문이다.

id 값 추가

  • id 값을 추가
  • @GeneratedValue를 추가하여 순차적으로 증가하게 함
  • 따라서, private Long id 는 자동으로 증가하는 숫자 값이고 User Table 객체의 PK 값인 ID가 된다.

Q. 그렇다면 해당 객체는 어떻게 저장하고 조회할 수 있을까?

A. Repository를 생성하면 된다.

 

Repository 폴더 추가 및 코드 작성

  • 패키지 안에 repository 폴더 생성
  • JpaRepository를 상속 받음으로써 많은 JPA 관련 메서드들을 지원받는다.

AllArgsConstructor

  • UserTest 코드 안에 AllArgsConstructor 에서 Error가 발생했다.
  • id 값을 추가해주지 않아서 발생

id 값 추가

  • id 값을 추가해주면 해결된다.

JpaRepository를 상속받는 것 만으로도 JpaRepository의 많은 것을 활용할 수 있다.

 

Test Code 만들기

[ctrl + shift + T] 단축키로 Repository Test 코드 만들기
Test Code 생성
test code 작성

  • @SpringBootTest로 Spring Context를 로딩해서 Test에 활용
  • @Autowired를 통해 UserRepository 가져오기 (의존성 추가)
  • crud() 메서드 test 코드 작성
  • save()로 User를 저장
  • findAll()로 전체를 조회

오류 발생

Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Syntax error in SQL statement "insert into [*]user (created_at, email, name, updated_at, id) values (?, ?, ?, ?, ?)"; expected "identifier"; SQL statement: ...

오류 메시지

원인

user 가 예약어라서 사용할 수 없음

 

해결 방법

해결 방법 : Class 명 변경

class 명 변경 User → Users

 

해결

해결

  • id는 1이 부여되었고, 위에는 NoArgsConstructor로 만들었기 때문에 Null 값이 들어갔다.

Q. 이런 메서드들은 어디에 있는 것일까?

JpaRepository 살펴보기

ctrl을 누른 상태로 JpaRepository를 클릭하면 JpaRepository를 살펴볼 수 있다.

JpaRepository는 PagingAndSortingRepository와 QueryByExampleExecutor를 상속 받는다.
정의된 메서드들

JPARepository 메서드 뜯어보기

List<T> findAll(); // table의 모든 data를 가져온다.
//test에서는 사용할지라도 실제 서비스에서는 성능적인 이슈로 잘 사용하지 않는다.

List<T> findAll(Sort sort); // 정렬 값이 추가된 메서드 

List<T> findAllById(Iterable<ID> ids); 
// id 값이 iterable(list)로 받아서 in 구문으로 조회해서 여러가지 Entity들을 조회 

<S extends T> List<S> saveAll(Iterable<S> entities);
// Entity를 list 형식으로 받아서 한번에 db에 반영하도록 한다. 

void flush();
// 현재 jpa context에서 가지고 있는 db 값을 db에 반영하도록 한다. 

<S extends T> S saveAndFlush(S entity); // 저장한 데이터를 바로 db에 반영

<S extends T> List<S> saveAllAndFlush(Iterable<S> entities);

default void deleteInBatch(Iterable<T> entities) {
	deleteAllInBatch(entities);
}
// Entity를 iterable(list의 상위 인터페이스) 형식으로 받아서 한꺼번에 지우기 

void deleteAllInBatch(Iterable<T> entities);
// 조건 없이 해당 테이블 모두 지우기 (실제 로직에서는 잘 안 쓰인다.)

void deleteAllByIdInBatch(Iterable<ID> ids);

void deleteAllInBatch();

T getOne(ID id); // id값으로 해당 Entity 조회 

T getById(ID id); 

T getReferenceById(ID id); 

<S extends T> List<S> findAll(Example<S> example); // example을 이용한 findAll

<S extends T> List<S> findAll(Example<S> example, Sort sort);

 

PagingAndSortingRepository 뜯어보기

  • CrudRepository를 상속 받고 있다.

PagingAndSortingRepository

Iterable<T> findAll(Sort sort);

Page<T> findAll(Pageable pageable);
// pageable parameter를 받아서 한번에 페이징을 쉽게 처리 

 

CrudRepository 뜯어보기

  • Repository를 상속 받고 있다.

CrudRepository

<S extends T> S save(S entity); // Entity에 대한 저장 

<S extends T> Iterable<S> saveAll(Iterable<S> entities);
// Entity의 묶음을 가지고 한번에 저장 

Optional<T> findById(ID id);
// Optional 객체로 매핑해서 return 해준다. 
// getOne()과는 동작이 조금 다르다. 

boolean existsById(ID id);
// 해당 객체의 존재 여부 확인 

Iterable<T> findAll();

Iterable<T> findAllById(Iterable<ID> ids);

long count(); // 전체 Entity의 개수 가져오기 

void deleteById(ID id); 

void delete(T entity); 

void deleteAllById(Iterable<? extends ID> ids); 

void deleteAll(Iterable<? extends T> entities); 

void deleteAll(); 
  • 많이 사용되는 메서드들은 CrudRepository에 정의되어있다.

Repository 뜯어보기

Repository

  • 아무것도 존재하지 않는다.
  • 최상위 interface에 있는 Repository는 JPA에서 사용하는 domain Repository 타입이라고 하는 것을 알려주기 위한 interface
  • 실제로 메서드에 대한 정의는 존재하지 않는다.

QueryByExampleExecutor 뜯어보기

QueryByExampleExecutor

<S extends T> Optional<S> findOne(Example<S> example);

<S extends T> Iterable<S> findAll(Example<S> example);

<S extends T> Iterable<S> findAll(Example<S> example, Sort sort);

<S extends T> Page<S> findAll(Example<S> example, Pageable pageable);

<S extends T> long count(Example<S> example);

<S extends T> boolean exists(Example<S> example);

<S extends T, R> R findBy(Example<S> example, Function<FluentQuery.FetchableFluentQuery<S>, R> queryFunction);

  • example을 활용한 메서드들이 있다.

2023 KAKAO Tech Campus_BackEnd 선택 과정
Spring JPA와 Security 강의 정리 내용입니다.

'💻 개발 > Spring' 카테고리의 다른 글

Framework와 Project  (0) 2023.11.29
Repository Interface 메소드 실습 (1)  (0) 2023.07.20
H2 DB 및 로그 설정  (0) 2023.07.18
Lombok 알아보기  (0) 2023.07.17
스프링 부트 프로젝트 생성  (0) 2023.07.17