延長のようなJPA-スペックは、Oracle関数BITAND、INSTR

JPAスペックgithubの:  https://github.com/wenhao/jpa-spec

このフレームワークを使用すると、私たちの戦いの条件は、次のコードの複雑さを簡素化することができます。

パブリックページの<person> のfindAll(SearchRequestリクエスト){ 
    仕様 <人>仕様=仕様<者> と()
            .EQ(StringUtils.isNotBlank(request.getName())、 "名前" 、request.getName()) GT( "年齢"、18 
            .between( "誕生日"、新しい日付()、新しい日付())
            .like( "ニックネーム"、 "%のOG%" 
            .build(); 

    ソートソート = Sorts.builder()
        .desc(StringUtils.isNotBlank(request.getName())、 "名前""誕生日" 
        .build(); 

    返す personRepository.findAll(仕様、新しい PageRequestを(0、15 、ソート)); 
}

これは、ページ+ソートクエリです。

しかし、我々はデータベース固有の機能を使用している場合は、このフレームワークによって提供された方法では十分ではありません、我々は拡大する必要があります。

私たちは、Oracleデータベースを使用している、それは我々が展開する必要があるBITAND、INSTRとして機能します:

JPA仕様のBITAND拡張子:

/ ** 
 *オラクルBITAND函数计算扣款规则rulebit 
 * 
 * @author :HKK 
 * @date:で作成された2019年7月24日10時34分
 * / 
パブリック クラス BitandSpecification <T> 拡張 AbstractSpecification <T> {
     プライベート文字列のプロパティ。
    プライベートリスト<BigDecimalの> 値。

    公共 BitandSpecification(Stringプロパティ、リスト<BigDecimalを> 値){
         この .property = プロパティ。
        これは、 = .values 値を、
    } 

    @Override 
    公共述語toPredicate(ルート<T>根、CriteriaQuery <?>クエリ、CriteriaBuilderのCB){ 

        BigDecimalの和が = values.stream(()のBigDecimalを低減::追加)に.get()。

        LiteralExpression <BigDecimalの> literalExpression = 新しい LiteralExpression <>(nullで、合計)。
 <BigDecimalの> ruleBit = cb.function( "BITAND" 
                。BigDecimalのクラス
                root.get(プロパティ)、literalExpression)。

        返すcb.greaterThan(ruleBit、BigDecimal.ZERO)。

    } 
}

JPAスペックINSTR拡張子:

/ ** 
 *オラクルINSTR函数计算扣款规则rulebit 
 * 
 * @author :HKK 
 * @date:で作成された2019年7月24日10:34 
 * / 
パブリック クラス IntstrSpecification <T> 拡張 AbstractSpecification <T> {
     プライベート文字列のプロパティ。
    プライベートString値。

    公共IntstrSpecification(Stringプロパティ、文字列値){
         この .property = プロパティ。
        この .VALUE = 値; 
    } 

    @Override 
    公共述語toPredicate(ルート<T>根、CriteriaQuery <?> クエリ、CriteriaBuilderのCB){

        LiteralExpression literalExpression = 新しい LiteralExpression(ヌル値)。
 <BigDecimalの> INSTR = cb.function( "INSTR" 
                。BigDecimalのクラス
                root.get(プロパティ)、literalExpression)。

        返すcb.greaterThan(INSTR、BigDecimal.ZEROを)。

    } 
}

二つの方法の追加:私たちは、その後、PredicateBuilderクラスを変更します

   / ** 
     *オラクル函数BITAND 
     * @paramのプロパティ
     * @paramのVAR 
     * @return 
     * / 
    公共 PredicateBuilder <T> BITAND(Stringプロパティ、リストのVAR){ 

        場合(!CollectionUtils.isEmpty(VAR)){
             この .predicate(新しいBitandSpecification(プロパティ、VAR)); 
        } 
        戻り これを
    } 

    / ** 
     *オラクル函数INSTR 
     * @paramのプロパティ
     * @paramのVaRの
     *の@return
     * / 
    パブリック PredicateBuilder <T> INSTR(Stringプロパティ、文字列VAR){ 

        場合(StringUtils.isNotBlank(VAR)){
             この .predicate(新しいIntstrSpecification(プロパティ、VAR))。
        } 
        戻り これを
    }

 

私たちは、コードの開発者の量を減らし、判定パラメータがnull渡して、いくつかの方法を追加しました:

/ ** 
     *値が空でない
     * @paramのプロパティ
     * @paramの値を
     * @return 
     * / 
    公共 PredicateBuilder <T> inWhereHasValues(文字列プロパティ、リスト値){
         IF(!CollectionUtils.isEmpty(値)){
             これ。 (プロパティ、値)で; 
        } 
        戻り これを; 
    } 

    / ** 
     * NULL値が空である場合である
     場合の値*空でない
     * @param プロパティ
     * @paramの
     * @return 
     / *
    公共 PredicateBuilder <T> inAndNull(Stringプロパティ、リスト値){
         場合(CollectionUtils.isEmpty(値)){
             戻り 、この.EQ(プロパティ、値)。

        } 
        リターン(プロパティ、値)で、
    } 

公共 PredicateBuilder <T> eqWhereHasValue(Stringプロパティは、オブジェクト...値){
         場合(値== NULL ){
             戻り 、これを
        } 
        場合(values.length == 1が){
             場合に(値は[0] == NULL ){
                 戻り 、これを; 
            } 
            場合(StringUtils.isBlank(String.valueOf(値[0 ]))){
                 戻り 、これを
            } 

        } 

        戻り EQ(、プロパティ、値)。
    }

 

私たちは、まだ始まったばかりの学生のJPSを助けたい、我々はコミュニティに戻って考えることができる:)

 

おすすめ

転載: www.cnblogs.com/hankuikui/p/11414579.html