ホームページ  >  記事  >  Java  >  JAVA Spring Data JPAの動的クエリコードの詳細説明

JAVA Spring Data JPAの動的クエリコードの詳細説明

Y2J
Y2Jオリジナル
2017-04-25 16:42:562400ブラウズ

spring Data JPA は永続化レイヤーの開発を大幅に簡素化しますが、実際のアプリケーションでは依然として動的なクエリが必要です。

たとえば、フロントエンドに複数の条件があり、その多くはオプションである場合、休止状態を使用する場合は、条件を判断してバックエンド SQL をカスタマイズできる必要があります。 , Spring Data JPA は開発を簡素化するだけでなく、サポートも提供します。

基準 2 によって実装された動的クエリを実装することにより、Repo インターフェースは汎用インターフェースである JpaSpecificExecutor インターフェースを継承する必要があります。

その後、クエリを実行するときに、動的クエリパラメータ、ページングパラメータなどを渡すだけです。

使い方はとても簡単ですが、その理由を理解するために、まず Criteria API を紹介しましょう。

Criteria API

コンパイラがクエリの構文の正確性チェックを実行できる場合、クエリは Java オブジェクトに対してタイプセーフです。 Java™ Persistence API (JPA) のバージョン 2.0 では、Criteria API が導入されています。これにより、初めて Java アプリケーションにタイプセーフなクエリが導入され、実行時にクエリを動的に構築するメカニズムが提供されます。この記事では、Criteria API と密接に関連する Metamodel API を使用して、動的でタイプセーフなクエリを作成する方法について説明します。

Spring Data JPA を使用する場合、Repo レイヤーが JpaSpecificExecutor インターフェイスを継承している限り、動的なクエリに Specific を使用できます。まず JpaSpecificExecutor インターフェイスを見てみましょう:

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); 
}

メソッドの 1 つは動的を返します。クエリのデータ構造。


javax.persistence.criteria.Predicate toPredicate(javax.persistence.criteria.Root<T> root,
javax.persistence.criteria.CriteriaQuery<?> query,
javax.persistence.criteria.CriteriaBuilder cb);

ここでは Java EE のすべての仕様が使用されています。もちろん、JPA 仕様を実装する他のデータ永続層フレームワークを選択することもできます。
ここで、Criteria API のいくつかの点をもう一度見てみる必要があります:

Criteria クエリは、エンティティ クラスなど、特定の永続化ユニットの管理対象エンティティに対して定義されるメタモデルの概念に基づいています。埋め込みクラスまたはマップされた親クラス。

CriteriaQuery インターフェイス: 特定のトップレベルのクエリ オブジェクトを表します。これには、select、from、where、group by、order by などのクエリのさまざまな部分が含まれます。 注: CriteriaQuery オブジェクトは、エンティティ タイプまたはエンティティ タイプにのみ適用されます。埋め込み型 Criteria クエリは機能します

Root インターフェイス: Criteria クエリのルート オブジェクトを表し、エンティティ タイプを定義し、以降のナビゲーションに必要な結果を取得できます。 SQL クエリ

1 : ルート インスタンスは型指定され、クエリの FROM 句に表示できる型を定義します。

2: クエリ ルート インスタンスは、エンティティ タイプを AbstractQuery.from メソッドに渡すことで取得できます。

3: 基準クエリ。複数のクエリ ルートを持つことができます。

4: AbstractQuery は CriteriaQuery インターフェイスの親クラスであり、クエリ ルートを取得するメソッドを提供します。 CriteriaBuilder インターフェイス: CritiaQuery の構築に使用されるビルダー オブジェクト Predicate: 実際には条件または条件の組み合わせと同等の単純または複雑な述語タイプ

サポートされているメソッドは非常に強力です。参考のために以下に例を示します。ここで、同様に、次の例に基づいて、より複雑なクエリを作成できます。

Repo インターフェイス:

public interface DevHREmpConstrastDao 
 extends JpaRepository<DevHREmpConstrast, Long>,JpaSpecificationExecutor<DevHREmpConstrast>

Query インスタンス 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(); 
  } 
 }; 
}

Query インスタンス 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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。