> Java > java지도 시간 > JAVA Spring Data JPA의 동적 쿼리 코드에 대한 자세한 설명

JAVA Spring Data JPA의 동적 쿼리 코드에 대한 자세한 설명

Y2J
풀어 주다: 2017-04-25 16:42:56
원래의
2493명이 탐색했습니다.

spring Data JPA는 지속성 계층 개발을 크게 단순화하지만 실제 애플리케이션에서는 여전히 동적 쿼리가 필요합니다.

예를 들어 프런트 엔드에 여러 조건이 있고 그 중 대부분은 선택 사항인 경우 백엔드 SQL을 사용자 정의할 수 있어야 합니다. 최대 절전 모드를 사용할 때 조건이 사용되는지 판단할 수 있습니다. 물론, Spring Data JPA는 개발을 단순화할 뿐만 아니라 지원도 제공합니다.

기준 2에 의해 구현된 동적 쿼리를 구현함으로써 Repo 인터페이스는 일반 인터페이스인 JpaSpecificationExecutor 인터페이스를 상속해야 합니다.

그런 다음 쿼리할 때 동적 쿼리 매개변수, 페이징 매개변수 등을 전달하면 됩니다.

사용법은 매우 간단하지만, 그 이유를 이해하기 위해 먼저 Criteria API를 소개하겠습니다.

기준 API

컴파일러가 쿼리에 대해 구문 정확성 검사를 수행할 수 있는 경우 쿼리는 Java 객체에 대해 유형이 안전합니다. JPA(Java™ Persistence API) 버전 2.0에는 처음으로 Java 애플리케이션에 유형이 안전한 쿼리를 제공하고 런타임 시 쿼리를 동적으로 구성하기 위한 메커니즘을 제공하는 Criteria API가 도입되었습니다. 이 문서에서는 Criteria API 및 밀접하게 관련된 Metamodel API를 사용하여 유형이 안전한 동적 쿼리를 작성하는 방법을 설명합니다.

Spring Data JPA를 사용할 때 Repo 레이어가 JpaSpecificationExecutor 인터페이스를 상속하는 한 동적 쿼리에 사양을 사용할 수 있습니다. 먼저 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); 
}
로그인 후 복사

를 볼 수 있습니다. 현재까지 5개의 메소드가 제공되었으며, 메소드의 매개변수와 반환값에는 의도가 명확하게 표현되어 있습니다. 매개변수 중 Pageable과 Sort는 비교적 간단해야 하며 각각 페이징 매개변수와 정렬 매개변수이며 초점은 먼저 이 인터페이스의 정의를 살펴보겠습니다.

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);
로그인 후 복사

여기에 사용된 모든 사양은 Java EE에 있습니다. 구체적인 구현을 위해 Hibernate를 사용합니다. 물론 JPA 사양을 구현하는 다른 데이터 지속성을 선택할 수도 있습니다. .레이어 프레임.
여기서 다시 Criteria API의 몇 가지 사항을 살펴봐야 합니다.

기준 쿼리는 특정 지속성 단위에 대해 관리되는 엔터티인 메타모델 개념을 기반으로 합니다. , 이러한 엔터티는 엔터티 클래스, 포함된 클래스 또는 매핑된 상위 클래스일 수 있습니다.

CriteriaQuery 인터페이스: select, from, where, group by, order by 등과 같은 쿼리의 다양한 부분을 포함하는 특정 최상위 쿼리 개체를 나타냅니다. 참고: CriteriaQuery 개체 엔터티 유형에서만 작동합니다. 또는 포함된 유형의 기준 쿼리가 작동합니다.

루트 인터페이스: 기준 쿼리의 루트 개체를 나타냅니다. 기준 쿼리의 쿼리 루트는 엔터티 유형을 정의하고 원하는 결과를 얻을 수 있습니다. 향후 탐색을 위해 관련됩니다. SQL 쿼리의 FROM 절은

1과 유사합니다. 루트 인스턴스가 입력되고 쿼리의 FROM 절에 나타날 수 있는 유형을 정의합니다.

2: 쿼리 루트 인스턴스는 엔터티 유형을 AbstractQuery.from 메서드에 전달하여 얻을 수 있습니다.

3: 여러 쿼리 루트를 가질 수 있는 기준 쿼리입니다.

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() 메서드에서 반환된 매개변수를 전달합니다.

위 내용은 JAVA Spring Data JPA의 동적 쿼리 코드에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿