일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- jQuery값전달
- values()
- 제네릭
- 벌크연산
- JPA
- javascriptcalendar
- Hibernate
- 페이징
- springflow
- 프로젝트생성
- calendar
- javaservlet
- joinfetch
- 대량쿼리
- jQueryUI
- namedQuery
- LIST
- jQuery값전송
- 엔티티직접사용
- JQuery
- fetchjoin
- fullcalendar
- JPQL
- 제너릭
- 스프링데이터흐름
- Generic
- 자바서블릿
- jscalendar
- 페치조인
- paging
- Today
- Total
가자공부하러!
Spring Data Common(1) - 개발환경 설정, 기초사용방법 본문
1. 개발환경 설정
1.1. 개발환경
- Spring Boot 2.2.1
- Java 8
- JPA v2.*, Hibernate v5.*
- postgres DB
1.2. 설정파일
- application.yml : datasource, ddl-auto option
- JpaRunner.class : JPA의 핵심인 EntityManager를 가지고 엔티티 영속화 작업을 수행해주는 클래스
2. Spring Data
2.1. 역할 : SQL, NoSQL 저장소 지원 프로젝트의 묶음
2.2. 구성
- Spring Data Common : 여러 저장소 지원 프로젝트의 공통 기능 제공
- Spring Data REST : 저장소의 데이터를 하이퍼미디어 기반 HTTP 리소스, REST API리소스로 제공하는 프로젝트
- Spring Data JPA : Spring Data Common이 제공하는 기능에 추가적으로 JPA 관련 기능 제공
- Spring Data JDBC
- Spring Data KeyValue
- Spring Data MongoDB
- Spring Data Redis
- Spring Data ...
3. Spring Data Common - Repository 기초 사용방법
3.1. 구조
- JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> extends Repository<T, ID>
- Repository 인터페이스는 마커 인터페이스
- @NoRepositoryBean : 다른 저장소용 레파지토리가 실제 빈을 만들어서 등록하는 것을 방지하기 위함 == 실제 레파지토리가 아님을 알려줌
- CrudRepository
<S extends T> S save(S entity);
<S extends T> Iterable<S> saveAll(Iterable<S> entities);
Optional<T> findById(ID id);
boolean existsById(ID id);
Iterable<T> findAll();
Iterable<T> findAllById(Iterable<ID> ids);
long count();
void deleteById(ID id);
void delete(T entity);
void deleteAll(Iterable<? extends T> entities);
void deleteAll();
- PagingAndSorting
Iterable<T> findAll(Sort sort);
Page<T> findAll(Pageable pageable);
- JpaRepository : 오버라이딩 메소드 다수
@Override List<T> findAll();
@Override List<T> findAll(Sort sort);
@Override List<T> findAllById(Iterable<ID> ids);
@Override <S extends T> List<S> saveAll(Iterable<S> entities);
void flush();
<S extends T> S saveAndFlush(S entity);
void deleteInBatch(Iterable<T> entities);
void deleteAllInBatch();
T getOne(ID id);
@Override <S extends T> List<S> findAll(Example<S> example);
@Override <S extends T> List<S> findAll(Example<S> example, Sort sort);
3.2. 사용방법
- 적당한 레파지토리 상속받아서 쓰면 됨
> 페이징 쿼리
package com.exam.demo.repo;
import com.exam.demo.domain.Post;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* JpaRepository가 갖는 메소드를 사용할 수 있으면서 직접 정의한 메소드도 사용할 수 있다
*/
public interface PostRepository extends JpaRepository<Post, Long> {
//특정 키워드를 갖는 엔티티의 수
long countByTitleContains(String title);
//특정 키워드를 갖는 목록을 찾는 메소드
Page<Post> findByTitleContains(String title, Pageable pageable);
}
package com.exam.demo.repo;
import com.exam.demo.domain.Post;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
@DataJpaTest //Data Access Layer에서만, Transactional옵션이 들어있기 때문에 아래 Test들에 대한 내용은 모두 롤
//@DataJpaTest는 디펜던시에 H2 DB가 있으면 H2에서만 테스트돌림(원래 쓰던 DB 말고)
public class PostRepositoryTest {
@Autowired
PostRepository postRepository;
@Test
@Rollback(false)//Transactional 옵션 때문에 하이버네이트가 쿼리를 안보내기 때문에 Rollback false로 설정해야 테스트 가
public void repositoryCrudTest(){
//Given
Post post = new Post();
post.setTitle("hello spring boot common");
Post newPost = postRepository.save(post);
//When
Page<Post> page = postRepository.findAll(PageRequest.of(0, 10));
//Then
assertThat(page.getTotalElements()).isEqualTo(1);
assertThat(page.getNumber()).isEqualTo(0);
assertThat(page.getSize()).isEqualTo(10);
assertThat(page.getNumberOfElements()).isEqualTo(1);
//When
postRepository.findByTitleContains("spring", PageRequest.of(0,10));
//Then
assertThat(page.getTotalElements()).isEqualTo(1);
assertThat(page.getNumber()).isEqualTo(0);
assertThat(page.getSize()).isEqualTo(10);
assertThat(page.getNumberOfElements()).isEqualTo(1);
//When
long spring = postRepository.countByTitleContains("spring");
//Then
assertThat(spring).isEqualTo(1);
}
}
- 공통으로 사용할 메소드를 모은 Repository를 직접 정의해서 사용 가능
package com.exam.demo.repo;
import com.exam.demo.domain.Comment;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.Repository;
import java.io.Serializable;
import java.util.List;
/**
* 여러 레파지토리에서 공통으로 사용하고 싶은 메소드가 있을 때 공통 메소드들을 설정하는 방법
*/
@NoRepositoryBean
public interface MyRepository<T, Id extends Serializable> extends Repository<T, Id> {
//타입 T와 T를 상속받는 하위타입 E까지 허용
<E extends T> E save(E entity);
List<T> findAll();
long count();
}
package com.exam.demo.repo;
import com.exam.demo.domain.Comment;
import org.springframework.data.repository.RepositoryDefinition;
import java.util.List;
/**
* Repository나 JpaRepository를 상속받을 때 너무 많은 메소드가 생기는게 싫은 경우
* @RepositoryDefinition 애노테이션을 활용하게되면
* 내가 정의한 메소드만 사용할 수 있도록 설정이 가능하다.
*
* 공통메소드를 모아둔 MyRepository가 Repository를 상속받는 경우에도
* MyRepository에 명시된 메소드만 사용할 수 있게된다.
*/
@RepositoryDefinition(domainClass = Comment.class, idClass = Long.class)
public interface CommentRepository extends MyRepository<Comment, Long>{
}
@Entity
@Getter @Setter
public class Comment {
@Id @GeneratedValue
private Long id;
private String comment;
}
'공부 > Spring Boot' 카테고리의 다른 글
Spring REST Docs(1) - 기초 환경설정 (0) | 2019.12.24 |
---|---|
Spring Data Common(2) - Null 처리, 쿼리 작성 방법 (0) | 2019.11.27 |
Logback 활용(Spring Boot 2.2.0) - 이메일로 전송 (0) | 2019.11.05 |
Spring Boot Hibernate 사용(JPA) (0) | 2019.10.28 |
Mybatis <foreach> 예문 (0) | 2019.10.23 |