* 리포지토리 계층
컨트롤러 작성이 끝났으면
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를 사용
..~~~~..