Spring Data JPA가 동적 조회를 실현하는 두 가지 방법

5281 단어 springdatajpa
앞말
일반적으로 업무 인터페이스를 쓰는 과정에서 각종 조회 조건을 동적 조합할 수 있는 인터페이스가 필요할 가능성이 높다.만약 우리가 조회 조건에 따라 하나의 방법을 조합하는 방법에 따라 쓴다면, 대량의 방법이 존재하고 번거로우며 유지하기가 상당히 어려울 것이다.동적 조회를 실현하려면 사실 SQL 문장 연결을 실현하는 것이다.실현이 아무리 복잡해도 기본적으로select의 필드,from이나join의 표,where 또는having의 조건을 포함한다.Spring Data JPA에는 검색 조건의 동적 조회를 실현하는 두 가지 방법이 있습니다. 두 가지 방법 모두 Criteria API를 사용했습니다.
Criteria API
이 API는 데이터베이스에 대한 질의를 구성하는 데 사용됩니다.
유형 안전.메타데이터 모델을 정의함으로써 프로그램 컴파일 단계에서 유형을 검사할 수 있다. SQL처럼 Mysql과 상호작용을 해야 유형 문제를 발견할 수 있는 것은 아니다.
다음은 메타데이터 모델입니다.클래스 이름의 마지막 문자가 밑줄이고 내부 구성원 변수와 UserInfo인 메타모델 클래스를 생성합니다.class라는 실체 클래스의 속성 값은 상대적입니다.

@StaticMetamodel(UserInfo.class)
public class UserInfo_ {
  public static volatile SingularAttribute<UserInfo, Integer> userId;
  public static volatile SingularAttribute<UserInfo, String> name;
  public static volatile SingularAttribute<UserInfo, Integer> age;
  public static volatile SingularAttribute<UserInfo, Long> high;
}
이식 가능.API는 구체적인 데이터베이스에 의존하지 않고 데이터베이스 유형에 따라 데이터베이스 유형에 대응하는 SQL을 생성할 수 있기 때문에 이식할 수 있다.
대상을 향하다.Criteria API는 CriteriaQuery, Predicate 등 다양한 유형과 객체의 구축 질의를 사용하여 객체를 대상으로 합니다.SQL을 직접 작성하는 경우 대상 문자열을 기준으로 합니다.
첫 번째: JPA의 Criteria API를 통해 구현
  • Entity Manager가 CriteriaBuilder 를 가져옵니다
  • CriteriaBuilder가 CriteriaQuery 를 생성합니다
  • CriteriaQuery에서 조회할 테이블을 지정하고 Root를 받습니다. Root는 조회할 테이블을 대표합니다
  • CriteriaBuilder 생성 조건 Predicate, Predicate는 SQL의 where 조건에 비해 여러 Predicate를 및, 또는 조작할 수 있습니다
  • EntityManager를 통해 TypedQuery 를 작성합니다
  • TypedQuery에서 질의를 수행하고 결과를 반환합니다
  • 
    public class UserInfoExtendDao {
    
     @PersistenceContext(unitName = "springJpa")
     EntityManager em;
    
     public List<UserInfo> getUserInfo(String name,int age,int high) {
       CriteriaBuilder cb = em.getCriteriaBuilder();
       CriteriaQuery<UserInfo> query = cb.createQuery(UserInfo.class);
    
       //from
       Root<UserInfo> root = query.from(UserInfo.class);
    
       //where
       Predicate p1 = null;
       if(name!=null) {
         Predicate p2 = cb.equal(root.get(UserInfo_.name),name);
         if(p1 != null) {
           p1 = cb.and(p1,p2);
         } else {
           p1 = p2;
         }
       }
    
       if(age!=0) {
         Predicate p2 = cb.equal(root.get(UserInfo_.age), age);
         if(p1 != null) {
           p1 = cb.and(p1,p2);
         } else {
           p1 = p2;
         }
       }
    
       if(high!=0) {
         Predicate p2 = cb.equal(root.get(UserInfo_.high), high);
         if(p1 != null) {
           p1 = cb.and(p1,p2);
         } else {
           p1 = p2;
         }
       }
       query.where(p1);
    
       List<UserInfo> userInfos = em.createQuery(query).getResultList();
       return userInfos;
     }
    }
    
    
    두 번째: JpaSpecificationExecutor 인터페이스를 위한 DAO 레이어 인터페이스
    JpaSpecificationExecutor는 다음과 같습니다. 방법 매개 변수 Specification 인터페이스에는 방법 toPredicate가 있습니다. 반환 값은 Criteria API의 Predicate이고 Predicate는 SQL의 where 조건에 비합니다.이전의 방법에 비해 이런 쓰기는 조회의 표가 어느 것인지 지정할 필요도 없고 Criteria API를 통해 정렬과 페이지를 나눌 필요도 없다. 새 Pageable,Sort 대상을 통해findAll 방법에 전달하면 된다. 간편하다.
    
    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);
    }
    UserInfoDao 구현 JpaSpecificationExecutor
    
    public interface UserInfoDao 
      extends PagingAndSortingRepository<UserInfo, String>, JpaSpecificationExecutor<UserInfo> {}
    Specification 구현
    
    public static Specification<UserInfo> getSpec(final String name,final int age,final int high) {
       return new Specification<UserInfo>() {
         @Override
         public Predicate toPredicate(Root<UserInfo> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
           Predicate p1 = null;
           if(name!=null) {
             Predicate p2 = cb.equal(root.get(UserInfo_.name),name);
             if(p1 != null) {
               p1 = cb.and(p1,p2);
             } else {
               p1 = p2;
             }
           }
    
           if(age!=0) {
             Predicate p2 = cb.equal(root.get(UserInfo_.age), age);
             if(p1 != null) {
               p1 = cb.and(p1,p2);
             } else {
               p1 = p2;
             }
           }
    
           if(high!=0) {
             Predicate p2 = cb.equal(root.get(UserInfo_.high), high);
             if(p1 != null) {
               p1 = cb.and(p1,p2);
             } else {
               p1 = p2;
             }
           }
    
           return p1;
         }
       };
     }
    
    
    프로젝트 코드:springdatajpademo_jb51.rar
    이상은 본문의 전체 내용입니다. 여러분의 학습에 도움이 되고 저희를 많이 응원해 주십시오.

    좋은 웹페이지 즐겨찾기