Spring Data JPA의 동적 조회 인스턴스
예를 들어 프론트에 여러 가지 조건이 있는데 이런 조건은 대부분이 선택할 수 있다. 그러면 프론트의 SQL은 맞춤형으로 제작할 수 있어야 한다. hibernate를 사용할 때 조건을 판단하여 SQL(HQL)을 연결할 수 있다. 물론 Spring Data JPA는 우리의 개발을 간소화하는 동시에 지원을 제공했다.
Criteria2가 실현하는 동적 조회를 실현하려면 우리의 Repo 인터페이스가 JpaSpecificationExecutor 인터페이스를 계승해야 합니다. 이것은 범용 인터페이스입니다.
그리고 조회할 때 동적 조회 파라미터, 페이지 파라미터 등을 전송하면 됩니다.
사용하기는 간단하지만 그 이유를 알기 위해 Criteria API를 소개합니다.
Criteria API
만약 컴파일러가 조회에 대해 문법 정확성을 검사할 수 있다면, 자바 대상에게 이 조회는 형식이 안전하다.Java™Persistence API(JPA)의 2.0 버전은 Criteria API를 도입했다. 이 API는 처음으로 유형 보안 조회를 Java 응용 프로그램에 도입하여 실행할 때 동적으로 조회를 구성하는 메커니즘을 제공한다.본고는 Criteria API와 이와 밀접한 관계를 가진 Metamodel API를 사용하여 동적 유형의 안전 조회를 작성하는 방법을 소개한다.
Spring Data JPA를 사용할 때 Repo 레이어가 JpaSpecificationExecutor 인터페이스를 계승하면 Specification을 사용하여 동적 조회를 할 수 있습니다. 먼저 JpaSpecificationExecutor 인터페이스를 보겠습니다.
public interface JpaSpecificationExecutor<T> {
T findOne(Specification<T> spec);
List<T> findAll(Specification<T> spec);
Page<T> findAll(Specification<T> spec, Pageable pageable);
List<T> findAll(Specification<T> spec, Sort sort);
long count(Specification<T> spec);
}
방법의 매개 변수와 반환 값이 그 의도를 뚜렷하게 나타내는 다섯 가지 방법을 제공한 것을 볼 수 있다.그 중의 매개 변수, Pageable과 Sort는 비교적 간단해야 한다. 각각 페이지 매개 변수와 정렬 매개 변수이다. 중점은 바로 Specification 매개 변수이다. 먼저 이 인터페이스의 정의를 보자.
public interface Specification<T> {
Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb);
}
그 중 하나는 동적 조회의 데이터 구조를 되돌리는 것이다.
javax.persistence.criteria.Predicate toPredicate(javax.persistence.criteria.Root<T> root,
javax.persistence.criteria.CriteriaQuery<?> query,
javax.persistence.criteria.CriteriaBuilder cb);
여기에서 사용하는 것은 모두 JavaEE의 규범이다. 구체적으로 본인이 사용한 것은 Hibernate이고 JPA규범을 실현한 다른 데이터 지구층 구조를 선택할 수 있다.Criteria API 중 일부를 다시 한 번 살펴봐야 합니다.
Criteria 조회는 모형의 개념을 바탕으로 한다. 모형은 구체적인 지구화 단원의 관리되는 실체를 위해 정의된 것이다. 이런 실체는 실체류, 삽입류 또는 비치는 부류가 될 수 있다.
CriteriaQuery 인터페이스: 특정한 최상위 검색 대상을 대표합니다. 검색의 각 부분을 포함합니다. 예를 들어 select,from,where,group by,order by 등 주의: CriteriaQuery 대상은 실체 형식이나 삽입식 형식의Criteria 조회에만 작용합니다.
Root 인터페이스: Criteria 쿼리의 루트 객체를 나타내며, Criteria 쿼리의 루트는 실체 유형을 정의하여 향후 탐색을 위해 원하는 결과를 얻을 수 있습니다. 이것은 SQL 쿼리의 FROM 자구와 유사합니다.
1: Root 인스턴스는 유형화되고 질의의 FROM 자구에 나타날 수 있는 유형을 정의합니다.
2: 루트 실례를 조회하면 하나의 실체 유형을 AbstractQuery에 전송할 수 있습니다.from 방법으로 획득.
3:Criteria 조회, 여러 개의 조회 루트가 있습니다.
4: AbstractQuery는 CriteriaQuery 인터페이스의 부류로 검색 루트를 얻을 수 있는 방법을 제공합니다.CriteriaBuilder 인터페이스: CritiaQuery를 구축하는 데 사용되는 구축자 대상Predicate: 간단하거나 복잡한 술어 유형으로 조건이나 조건 조합에 해당한다
그 중에서 지원하는 방법은 매우 강력하다. 다음은 예시를 하나 제시한다. 여러분은 참고할 수 있다. 마찬가지로 예시에 따라 더욱 복잡한 조회를 작성할 수 있다.
Repo 커넥터:
public interface DevHREmpConstrastDao
extends JpaRepository<DevHREmpConstrast, Long>,JpaSpecificationExecutor<DevHREmpConstrast>
질의 인스턴스 1:
/**
*
*/
private Specification<DevHREmpConstrast> where(
final String corg,final String name,final String type,final String date,final String checker){
return new Specification<DevHREmpConstrast>() {
@Override
public Predicate toPredicate(Root<DevHREmpConstrast> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
List<Predicate> predicates = new ArrayList<Predicate>();
//
if(corg!=null&&!corg.equals("")){
List<String> orgIds = organizationDao.findByName("%"+corg+"%");
if(orgIds.size()>0&&orgIds.size()<1000)
predicates.add(root.<String>get("confirmOrgNo").in(orgIds));//confirmOrgNo
}
//
if(name!=null&&!name.equals("")){
List<String> userIds = userDao.findByName(name);
if(userIds.size()>0&&userIds.size()<1000)//
predicates.add(root.<String>get("hrUserName").in(userIds));
}
//
if(type!=null&&!type.equals(""))
predicates.add(cb.equal(root.<String>get("hrUpdateType"),type));
//
if(date!=null&&!date.equals("")){
//
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Date startDate;
Date endDate;
try {
startDate = format.parse(date);
} catch (ParseException e) {
startDate = new Date(946656000000L);//2000 01 01
}
endDate = startDate;
Calendar calendar = Calendar.getInstance() ;
calendar.setTime(endDate);
calendar.add(Calendar.DATE, 1);
endDate = calendar.getTime();
calendar = null;
predicates.add(cb.between(root.<Date>get("insDate"),startDate,endDate));
}
//
if(checker!=null&&!checker.equals("")){
List<String> userIds = userDao.findByName(checker);
if(userIds.size()>0&&userIds.size()<1000)//
predicates.add(root.<String>get("confirmUserId").in(userIds));
}
return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
}
};
}
질의 인스턴스 2:
/**
*
*/
private Specification<DevHREmpConstrast> where(
final String corg,final String name,final String type,final String date,final String checker){
return new Specification<DevHREmpConstrast>() {
@Override
public Predicate toPredicate(Root<DevHREmpConstrast> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
List<Predicate> predicates = new ArrayList<Predicate>();
//
if(corg!=null&&!corg.equals("")){
List<String> orgIds = organizationDao.findByName("%"+corg+"%");
if(orgIds.size()>0&&orgIds.size()<1000)
predicates.add(root.<String>get("confirmOrgNo").in(orgIds));//confirmOrgNo
}
//
if(name!=null&&!name.equals("")){
List<String> userIds = userDao.findByName(name);
if(userIds.size()>0&&userIds.size()<1000)//
predicates.add(root.<String>get("hrUserName").in(userIds));
}
//
if(type!=null&&!type.equals(""))
predicates.add(cb.equal(root.<String>get("hrUpdateType"),type));
//
if(date!=null&&!date.equals("")){
//
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Date startDate;
Date endDate;
try {
startDate = format.parse(date);
} catch (ParseException e) {
startDate = new Date(946656000000L);//2000 01 01
}
endDate = startDate;
Calendar calendar = Calendar.getInstance() ;
calendar.setTime(endDate);
calendar.add(Calendar.DATE, 1);
endDate = calendar.getTime();
calendar = null;
predicates.add(cb.between(root.<Date>get("insDate"),startDate,endDate));
}
//
if(checker!=null&&!checker.equals("")){
List<String> userIds = userDao.findByName(checker);
if(userIds.size()>0&&userIds.size()<1000)//
predicates.add(root.<String>get("confirmUserId").in(userIds));
}
return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
}
};
}
그리고dao층 방법을 호출하여where () 방법으로 되돌아오는 파라미터를 전송하면 됩니다.이상은 본문의 전체 내용입니다. 여러분의 학습에 도움이 되고 저희를 많이 응원해 주십시오.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
thymeleaf로 HTML 페이지를 동적으로 만듭니다 (spring + gradle)지난번에는 에서 화면에 HTML을 표시했습니다. 이번에는 화면을 동적으로 움직여보고 싶기 때문에 입력한 문자를 화면에 표시시키고 싶습니다. 초보자의 비망록이므로 이상한 점 등 있으면 지적 받을 수 있으면 기쁩니다! ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.