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を助けたい、我々はコミュニティに戻って考えることができる:)