[Spring Boot] MVC 아키텍처 - Repository

정원준·2024년 12월 19일

Back-End

목록 보기
6/9

해당 포스트에선 레파지토리에 대해 설명해보겠다.

1. Repository

레파지토리데이터와 직접적으로 접근한다.
스프링부트에선 주로 JPA와 함께 쓰이며, 주로 데이터를 저장, 조회, 수정, 삭제(CRUD)하는 작업을 담당한다.
컨트롤러, 서비스, DTO 등등은 자바 클래스로 생성하지만 레파지토리는 인터페이스로 생성한다.
형태는 다음과 같다.

2. Repository 문법

JPA를 사용할 경우 기본적인 문법은 다음과 같다.
public interface 레파지토리명 extends JpaRepository<Entity명, id타입>{}
기본적인 CRUD는 JpaRepository에서 제공된다.
따라서, 중괄호 {} 안에는 메서드를 넣으면 된다.

3. JPA 메서드

이건 JPA 포스팅들이 많이 있으니까 간단하면서 자주 사용되는 메소드들만 소개해보겠다. 메서드는 기본 메서드와 쿼리 메서드로 나눠진다고 보면 된다.

기본메서드

  • save(S entity) - 엔티티를 저장하거나 업데이트한다.
// ex)
repository.save(entity);
  • findById(ID id) - ID를 기반으로 엔티티를 조회한다.
// ex)
Optional<MyEntity> entity = repository.findById(id);
  • findAll() - 모든 엔티티를 조회한다.
// ex)
List<MyEntity> entities = repository.findAll();
  • deleteById(ID id) - ID를 기반으로 엔티티를 삭제한다.
// ex)
repository.deleteById(id);
  • deleteAll() - 모든 엔티티를 삭제한다.
// ex)
repository.deleteAll();
  • count() - 엔티티의 개수를 반환한다.
// ex)
long count = repository.count();

쿼리메서드

  • findBy + 필드명
// ex)
List<MyEntity> findByName(String name);
  • findBy + 필드명 + 조건
// ex1) 
List<MyEntity> findByAgeGreaterThan(int age);

//ex2) 
List<MyEntity> findByStatusAndType(String status, String type);
  • findTop 또는 findFirst
// ex)
MyEntity findTopByOrderByIdDesc();

4. QueryDSL

JPA 메서드하면 빠질 수 없는 게 Query인데,, @Query나 Native Query가 아닌 QueryDSL을 가져온 이유는 아무래도 사람들한테 사랑받는 녀석이니까..ㅎ

그래서 이게 뭔데?!

얘는 이제.. 흠 쉽게 말하면 자바 코드로 JPQL을 작성한 녀석이라고 보면 된다.
JPQL(Java Persistence Query Language)은 또 뭐냐면 테이블을 대상으로 쿼리하는 SQL과는 다르게 JPA에서 제공하는 엔티티 객체를 대상으로 쿼리하는 녀석이다.
※ JPQL도 결국 SQL로 변환
짧게 설명하는 거니까 특징 또한 짧게 설명!

  1. 자바 코드로 작성되므로 컴파일 시점에서 문법 오류를 발견할 수 있다.
  2. 자바 코드로 작성되기에 동적 쿼리 작성에 편리하다.
  3. 코드가 직관적이다.
  4. 코드의 재사용성이 증가하고 유지보수에 용이하다.

사용법

queryFactory를 사용해야하고 SQL 쿼리문과 비슷하게 작성하면 된다. 자세한 문법들은 다른 포스팅을 찾아보는 게 더 빠를 것이다. 예제들을 보여주고 마치고자 한다.

  • 단일 조건 조회
  List<User> users = queryFactory
    .selectFrom(user)
    .where(user.status.eq("ACTIVE"))
    .fetch();
  • 복잡 조건 조회
List<User> users = queryFactory
    .selectFrom(user)
    .where(
        user.name.containsIgnoreCase("john")
            .and(user.age.goe(20))
            .and(user.status.eq("ACTIVE"))
    )
    .fetch();
  • 정렬 및 페이징
List<User> users = queryFactory
    .selectFrom(user)
    .where(user.status.eq("ACTIVE"))
    .orderBy(user.age.desc())
    .offset(0)
    .limit(10)
    .fetch();
  • 그룹 및 집계
List<Tuple> result = queryFactory
    .select(user.status, user.age.avg())
    .from(user)
    .groupBy(user.status)
    .fetch();

마치며

레파지토리에 대해서는 따로 많이 얘기를 쓸 부분이 없어서 사실상 Query 부분이 더 많은 거 같지만,,ㅎ 암튼 기본 스프링 구조는 다 작성한 듯 하다!

충격적인 사실을 하나 알게되었다. JPA를 extend하는 레파지토리는 @Repository를 사용하지 않아도 컨테이너에 등록된다는 사실..

0개의 댓글