Spring Data Jpa란 spring framework에서 JPA를 편리하게 사용할 수 있도록 지원하는 프로젝트이며
CRUD 처리를 위한 공통 인터페이스를 제공해준다.
동아리에서 프로젝트를 진행하며 Spring Data Jpa를 사용하여 레퍼지토리를 만들었는데
전에 Jpa만 사용하던 방식보다 훨씬 편리하기 때문에 과정을 기록해보려 한다.
바로 시작하겠다.
Entity 생성
우선 엔티티를 생성해야 한다. User에 관해 생성할 것이므로 User라는 클래스를 하나 만들었다.
User.java
@Getter
@NoArgsConstructor
@Table(name = "USER")
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "userId")
private Long userId;
@Column(name = "username", nullable = false)
private String username;
@Column(name = "email", nullable = true)
private String email;
@Column(name = "role",nullable = false)
@Enumerated(EnumType.STRING)
private Role role;
@Column(name = "kakaoId",nullable = false)
private String kakaoId;
@Column(name = "imgUrl",nullable = false)
private String imgUrl;
@Builder
public User(String username, String email, String kakaoId, Role role, String imgUrl) {
Assert.hasText(username, "username must not be empty");
Assert.hasText(kakaoId, "kakaoId must not be empty");
Assert.hasText(role.name(), "role must not be empty");
Assert.hasText(imgUrl, "imgUrl must not be empty");
this.username = username;
this.email = email;
this.kakaoId = kakaoId;
this.role = role;
this.imgUrl = imgUrl;
}
이번엔 조금 특별하기 enum을 사용해 User Role을 지정해주었다.
Role 부분에 @Enumerated 어노테이션이 있어야 DB에 저장되는 상황에 String 형태로 저장시킬 수 있다.
enum을 엔티티 컬럼으로 사용할 때 참고하자. 그리고 이번엔 생성자에 @Builder 어노테이션을 사용했다.
생성자 방식
이렇게 생긴 생성자 방식과는 다르게
Builder 방식
이런 형태로 객체를 생성 방식이다. 이런 것이 있다는 것 정도 알아두자.
엔터티 생성이 끝났으면 사실상 끝이다.
Spring Data Jpa를 사용해 바로 Repository를 만들어보자
UserRepository Interface 생성
UserRepository.java
public interface UserRepository extends JpaRepository<User, Long> {
User save(User user);
Optional<User> findByUserId(Long userId);
Optional<User> findByUsername(String Username);
}
Jpa만 사용하는 개발방식에서는 interface를 만들고 구현체를 만들어 implement를 통해 Repository를 생성했지만
Spring Data Jpa 를 사용하면 레퍼지토리에 JpaRepository 를 extends 해야 한다.
SpringBoot는 기본적인 CRUD가 가능하도록 JpaRepository 를 제공한다.
상속받을 때는 <Entity, ID> 가 들어가는데 ID는 Long을 작성해주면 된다.
대신 인터페이스를 상속받아 사용하는 것이기 때문에 '메서드의 이름' 을 정해진 대로 지정해야 기능을 구현할 수 있다.
기본 기능
method | 기능 |
save() | 레코드 저장 (insert, update) |
findOne() | primary key로 레코드 한건 찾기 |
findAll() | 전체 레코드 불러오기. 정렬(sort), 페이징(pageable) 가능 |
count() | 레코드 갯수 |
delete() | 레코드 삭제 |
조회 기능
method | 설명 |
findBy로 시작 | 쿼리를 요청하는 메서드 임을 알림 |
countBy로 시작 | 쿼리 결과 레코드 수를 요청하는 메서드 임을 알림 |
위의 findBy에 이어 해당 Entity 필드 이름을 입력하면 검색 쿼리를 실행한 결과를 전달한다.
SQL의 where 절을 메서드 이름을 통해 전달한다고 생각하면 된다.
메서드의 반환형이 Entity 객체이면 하나의 결과만을 전달하고, 반환형이 List라면 쿼리에 해당하는 모든 객체를 전달한다.
Query 메소드에 포함할 수 있는 키워드
메서드 이름 키워드 | 샘플 | 설명 |
And | findByEmailAndUserId(String email, String userId) | 여러필드를 and 로 검색 |
Or | findByEmailOrUserId(String email, String userId) | 여러필드를 or 로 검색 |
Between | findByCreatedAtBetween(Date fromDate, Date toDate) | 필드의 두 값 사이에 있는 항목 검색 |
LessThan | findByAgeGraterThanEqual(int age) | 작은 항목 검색 |
GreaterThanEqual | findByAgeGraterThanEqual(int age) | 크거나 같은 항목 검색 |
Like | findByNameLike(String name) | like 검색 |
IsNull | findByJobIsNull() | null 인 항목 검색 |
In | findByJob(String … jobs) | 여러 값중에 하나인 항목 검색 |
OrderBy | findByEmailOrderByNameAsc(String email) | 검색 결과를 정렬하여 전달 |
더 자세한 키워드와 쿼리를 보고 싶다면 아래 JPA 레퍼런스를 참고하면 된다.
Bean 등록
JpaRepository를 상속받으면 자동으로 '스프링 빈'으로 등록된다. 레퍼지토리에 @Repository 를 설정할 필요도 없다.
하지만 @EnableJpaRepositories 어노테이션을 Config 클래스에 설정해 줄 필요가 있다.
SpringBoot는 자동으로 설정이 된다고 하지만, 이런 것도 있다는 학습을 위한 목적으로 설정해보았다.
AppConfig.java
@Configuration
@EnableJpaRepositories(basePackages = "dnd.project.dnd6th7worryrecordservice")
public class AppConfig {
@Bean
public UserServiceImpl userService() { return new UserServiceImpl();}
}
@Bean 어노테이션으로 등록하는 대신 @EnableJpaRepositories 어노테이션을 사용해 코드가 짧아졌다.
@EnableJpaRepositories 는 basePackages 하위에 있는 모든 JpaRepository 상속체들을 Bean으로 등록해준다.
따라서 제일 상위 패키지를 적어주면 끝난다.
사용 시에는 위처럼 작성하면 정상적으로 작동하는 것을 확인할 수 있다.
Reference: