프로그래밍/백엔드 스프링부트

리포지토리 계층

Mt.Hwang 2025. 5. 2. 22:51

 * 리포지토리 계층 

컨트롤러 작성이 끝났으면
 1. 데이터베이스 SQL 문장 작성
 2. 엔티티 생성
 3. 리포지토리 생성
 4. 서비스 코드 작성
의 순서대로 개발한다

다만, 서비스 코드를 작성하면서 리포지토리 메서드를 작성하거나 컨트롤러의 요청/응답 데이터를 수정하기도 한다


리포지토리와 엔티티는 형식에 맞춰서 작성하면 
스프링 데이터 JPA가 알아서 함수를 만들어주거나 값을 채워넣어준다


리포지토리 인터페이스 메서드
 1. 삽입 : save()
 2. select : findBy 메서드
 3. 삭제 : deleteBy 메서드
 4. 수정 : @Modifying & @Query, 혹은 엔티티의 필드 수정 후 save(). 극단적인 경우 delete 후 save()


참고로 쿼리 메서드에는 
 1. findBy 
 2. existsBy
 3. countBy
 4. deleteBy
 5. removeBy
등의 다양한 접두사가 있다

..~~~~..

 * SQL 문장

SQL 문장은 .sql 파일에 작성

저장 위치는
src/main/resources/

 1. schema.sql : DDL 문장. 즉, 테이블 생성 코드 작성
 2. data.sql : DML 문장. 즉, 데이터 입력 코드 작성

서비스 코드를 실험할 때 실제 데이터가 필요한 경우가 있는데
이때 data.sql에 데이터를 넣으면서 준비한다


.sql 파일의 실행은
aplication.yml 등의 설정 파일에 따로 설정해야 된다

ex)
spring:
  sql:
    init:
      mode: always

schema.sql, data.sql은 자동 실행 대상이며
별도의 설정이 없으면 H2, HSQL 등 내장 DB에서만 실행

..~~~~..

 * 엔티티 생성

엔티티 클래스는 domain 패키지에 저장

엔티티 클래스 : 데이터베이스 테이블에 매핑되는 객체. 테이블의 상태를 표현한다

번외로 
DAO 객체 : 데이터베이스와 직접적인 상호작용 (CRUD)을 하는 Repository 객체


사용 애너테이션은
 1. @Entity : 엔티티로 등록
 2. @Table : 매핑 테이블 지정
 3. @Id : 기본 키로 지정
 4. @IdClass : 기본 키로 여러 속성을 쓸 때 사용
 5. @GeneratedValue : 기본키 생성 방법 지정
 6. @Column : 매핑 속성 지정
 7. @ManyToOne : 다대일 관계 명시
 8. @OneToMany : 일대다 관계 명시
 9. @ManyToMany : 다대다 관계 명시
 10. @OneToOne : 일대일 관계 명시
 11. @JoinColumn : 외래키 명시
 12. @Enumerated : Enum 타입 지정
 13. @Embedded : 복합값을 쓸 때 사용
 14. @Version : 낙관적 락 처리

..~~~~..

 * 리포지토리 인터페이스

JpaRepository 인터페이스를 상속하면 스프링 데이터 JPA가 알아서 구현해준다

public interface 엔티티명Repository extends JpaRepository<E, P> {}

 1. E : 엔티티 클래스
 2. P : 주키의 클래스 or Wrapper

인터페이스 안에 findBy 메서드를 작성하면 이 역시 스프링 데이터 JPA가 알아서 구현해준다

..~~~~..

 * 리포지토리 애너테이션

 1. @Transactional
 2. @Modifying
 2. @Query


@Transactional
클래스 및 메서드에 결합
트랜잭션 작업을 명시
스프링 데이터 JPA의 delete, save, update 등의 쓰기 작업은 반드시 트랜잭션 내에서 수행되어야 하기 떄문에 사용


@Modifying
리포지토리 메서드에 결합
SELECT이 아닌 DML sql을 쓸 때 명시한다
따라서 @Transactional과 함께 사용해야 한다

..~~~~..

 * @Query 쿼리 메서드

@Query("sql 문장") 형식으로 sql 문장을 직접 명시

이때 조건, 값으로 넣는 부분에는 = :변수명을 사용하고
매개변수에 @Param("변수명") 애너테이션을 붙여준다


즉, @Query 쿼리 메서드 작성 순서는
 1. 리포지토리 메서드에 @Query 사용
 2. @Query의 매개변수에 sql 문장 작성
 3. sql 문장을 작성할 때 조건, 값 부분에는 = :변수명 사용
 4. 리포지토리 메서드의 매개변수 부분에 @Param("변수명")을 명시함으로써 sql 문장의 변수와 매개변수 매핑
 5. SELECT 문장이 아닌 DML 문장인 경우 @Modifying 명시


ex)
@Query("SELECT g FROM Group g WHERE g.groupId = :groupId")
List<Group> findByGroupId(@Param("groupId") int groupId);

@Query(value = "SELECT * FROM group_table WHERE group_id = :groupId", nativeQuery = true)
List<Group> findByGroupIdNative(@Param("groupId") int groupId);

..~~~~..

 * save()

형식은
리포지토리 객체.save(엔티티 객체)

ex)
interface GroupRepository extends JpaRepository<Group, String> {}
...

@Autowired
private GroupRepository groupRepository
...

Group newGroup = new Group()
groupRepository.save(newGroup)

..~~~~..

 * findBy 메서드

findBy 메서드 : 데이터베이스 테이블에서 튜플을 검색하는 쿼리 메서드

메서드명은 주로
 1. findByA1()
 2. findByA1AndA2()
 3. findByA1OrA2()

리턴 타입은 주로 
 1. 여러 결과 시 List<T> 사용
 2. 단일 결과 시 Optional<T> 혹은 T 사용

ex)
엔티티명이 Group
검색에 사용하는 필드가 int groupId인 경우
List<Group> findByGroupId(int groupId);
Group findByGroupId(int groupId);

기본적으로 리턴 타입은 
 1. 엔티티 객체
 2. 엔티티를 담은 컨테이너
 3. DTO 클래스
가 좋다
스프링 데이터 JPA가 리턴 값 역시 알아서 만들어주는데 쿼리 메서드의 리턴값을 알아서 맞춰주기가 쉽지 않기 떄문

..~~~~..

 * deleteBy 메서드

형식은
int deleteBy...()

findBy 메서드와 마찬가지로
속성명-관계-속성명 이런식으로 작성한다


리턴값인 int는 delete 작업으로 인해 영향을 받은 튜플 수를 나타냄


deleteBy 메서드를 사용하는 클래스 및 메서드는 @Transactional이 필요
트랜잭션에서 delete의 쓰기 작업을 하기 위한 것

..~~~~..

 * 수정 메서드

Update 작업은 @Modifying & @Query를 사용

..~~~~..

'프로그래밍 > 백엔드 스프링부트' 카테고리의 다른 글

DAO와 DTO  (0) 2025.05.02
도메인 모델  (0) 2025.05.02
서비스 계층  (0) 2025.05.02
컨트롤러 계층  (0) 2025.05.02
스프링 부트 계층  (0) 2025.05.02