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 중국어 웹사이트의 기타 관련 기사를 참조하세요!