Spring Data JPA의 동적 조회 인스턴스

8210 단어 springdatajpa동태
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 () 방법으로 되돌아오는 파라미터를 전송하면 됩니다.
이상은 본문의 전체 내용입니다. 여러분의 학습에 도움이 되고 저희를 많이 응원해 주십시오.

좋은 웹페이지 즐겨찾기