[Spring JPA #25] Spring JPA Specification
- Spring/Spring JPA
- 2019. 2. 4. 22:30
반응형
| Spring JPA Specification
Spring JPA Specification은 Spring JPA에서 제공하는 검색 조건을 메서드 형태로 추상화하여 Repository 인터페이스에서 해당 검색 조건을 조합하고 쿼리하기 쉽게 할 수 있는 기능입니다.
| Spring JPA Specification 예제
프로젝트 구조
+---src
| +---main
| | +---java
| | | \---com
| | | \---tutorial
| | | \---springboot
| | | Application.java
| | | Comment.java
| | | CommentRepository.java
| | | CommentSpecs.java
| | |
| | \---resources
| | | application.properties
| | |
| | +---static
| | \---templates
| \---test
| \---java
| \---com
| \---tutorial
| \---springboot
| ApplicationTests.java
의존성 관리
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
설정 관리
Intllij 기준 Setting -> Compiler -> Annotation Processor에 다음과 같이 설정합니다.
설정후 mvn compile 명령어로 아래와 같은 도메인 클래스를 생성해야 합니다.
@Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor")
@StaticMetamodel(Comment.class)
public abstract class Comment_ {
public static volatile SingularAttribute<Comment, Post> post;
public static volatile SingularAttribute<Comment, String> comment;
public static volatile SingularAttribute<Comment, Boolean> best;
public static volatile SingularAttribute<Comment, Long> id;
public static volatile SingularAttribute<Comment, Integer> up;
public static volatile SingularAttribute<Comment, Integer> down;
public static final String POST = "post";
public static final String COMMENT = "comment";
public static final String BEST = "best";
public static final String ID = "id";
public static final String UP = "up";
public static final String DOWN = "down";
}
소스 코드
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@Entity
@Data
public class Comment {
@Id
@GeneratedValue
private Long id;
private String comment;
@ManyToOne
private Post post;
private int up;
private int down;
private boolean best;
}
public interface CommentRepository extends JpaRepository<Comment, Long>, JpaSpecificationExecutor<Comment> {
}
- JpaSpecifiactionExecutor를 추가하여 Specification을 Repository의 메서드에서 사용할 수 있게 명시해야합니다.
public class CommentSpecs {
public static Specification<Comment> isBest() {
return new Specification<Comment>() {
@Override
public Predicate toPredicate(Root<Comment> root,
CriteriaQuery<?> query,
CriteriaBuilder builder) {
return builder.isTrue(root.get(Comment_.best));
}
};
}
public static Specification<Comment> isGood() {
return new Specification<Comment>() {
@Override
public Predicate toPredicate(Root<Comment> root,
CriteriaQuery<?> criteriaQuery,
CriteriaBuilder criteriaBuilder) {
return criteriaBuilder.greaterThan(root.get(Comment_.up), 10);
}
};
}
}
- Comment 엔티티의 스펙을 정의합니다. Predicate 인터페이스를 반환하여 이 조건이 맞는지 확인하는 절차를 거치게 됩니다. CriteriaBuilder 클래스를 통하여 조건문을 정의할 수 있고 정의된 스펙들은 조합하여 쓸 수 있습니다.
테스트 코드
@RunWith(SpringRunner.class)
@DataJpaTest
public class ApplicationTests {
@Autowired
CommentRepository commentRepository;
@Test
public void specs() {
commentRepository.findAll(CommentSpecs.isBest());
}
}
반응형
'Spring > Spring JPA' 카테고리의 다른 글
[Spring JPA #24] Spring JPA Projection (0) | 2019.02.02 |
---|---|
[Spring JPA #23] Spring JPA EntityGraph (1) | 2019.02.02 |
[Spring JPA #22] Spring JPA Named Parameter, SpEL (0) | 2019.02.02 |
[Spring JPA #21] Spring JPA 쿼리 메서드 및 정렬 (0) | 2019.02.02 |
[Spring JPA #20] 스프링 부트 Spring JPA 엔티티 저장 메커니즘 (0) | 2019.02.02 |
이 글을 공유하기