休止状態のカスタム条件

前の記事で、 Hibernateにカスタムデータ型を格納する方法を教える方法について説明しました。 次に、サンプルをフィルタリングするときにこのデータを使用してみましょう。 取得したい結果を宣言します。
  1. String filteringTag = "habr" ; Session session = ... ; Criteria criteria = session. createCriteria ( StringArrayContainer. class ) ; criteria. add ( new StringArrayContainsCriterion ( "tags" , filteringTag ) ) ; List containers = criteria. list ( ) ; // , "habr" ...
  2. String filteringTag = "habr" ; Session session = ... ; Criteria criteria = session. createCriteria ( StringArrayContainer. class ) ; criteria. add ( new StringArrayContainsCriterion ( "tags" , filteringTag ) ) ; List containers = criteria. list ( ) ; // , "habr" ...
  3. String filteringTag = "habr" ; Session session = ... ; Criteria criteria = session. createCriteria ( StringArrayContainer. class ) ; criteria. add ( new StringArrayContainsCriterion ( "tags" , filteringTag ) ) ; List containers = criteria. list ( ) ; // , "habr" ...
  4. String filteringTag = "habr" ; Session session = ... ; Criteria criteria = session. createCriteria ( StringArrayContainer. class ) ; criteria. add ( new StringArrayContainsCriterion ( "tags" , filteringTag ) ) ; List containers = criteria. list ( ) ; // , "habr" ...
  5. String filteringTag = "habr" ; Session session = ... ; Criteria criteria = session. createCriteria ( StringArrayContainer. class ) ; criteria. add ( new StringArrayContainsCriterion ( "tags" , filteringTag ) ) ; List containers = criteria. list ( ) ; // , "habr" ...
  6. String filteringTag = "habr" ; Session session = ... ; Criteria criteria = session. createCriteria ( StringArrayContainer. class ) ; criteria. add ( new StringArrayContainsCriterion ( "tags" , filteringTag ) ) ; List containers = criteria. list ( ) ; // , "habr" ...


最初に、検索条件のユニバーサル実装を作成します。 これを行うには、StringArrayCustomType.nullSafeGetメソッドとStringArrayCustomType.nullSafeSetメソッドを少し変更します。つまり、列に格納されている値をスペースで囲みます。 (7行目と25行目の変更)
  1. @Override
  2. public Object nullSafeGet ( ResultSet rs、 String [ ] names、 Object owner ) throws HibernateException、 SQLException {
  3. 文字列値= ( 文字列 )休止状態。 テキスト nullSafeGet ( rs、names [ 0 ] ) ;
  4. if ( value == null ) {
  5. nullを 返し ます 。
  6. } else {
  7. 文字列 [ ]配列= StringUtils。 split (値。trim ( ) '' ) ;
  8. for ( int i = 0 ; i <配列の長さ ; i ++ ) {
  9. 配列[ i ] = WhitespaceEscapeUtil。 unescape (配列[ i ] ) ;
  10. }
  11. 配列を返し ます。
  12. }
  13. }
  14. @Override
  15. public void nullSafeSet ( PreparedStatement st、 Object value、 int index ) throws HibernateException、 SQLException {
  16. if ( value == null ) {
  17. 休止状態 テキスト nullSafeSet ( st、 null 、index ) ;
  18. } else {
  19. 文字列 [ ]配列= ( 文字列 [ ] )値;
  20. 文字列 [ ] copy = 新しい 文字列 [配列。 長さ ] ;
  21. for ( int i = 0 ; i <配列の長さ ; i ++ ) {
  22. copy [ i ] = WhitespaceEscapeUtil。 escape (配列[ i ] ) ;
  23. }
  24. 休止状態 テキスト nullSafeSet ( st、 '' + StringUtils。join ( copy、 '' ) + '' 、index ) ;
  25. }
  26. }

ここで、org.hibernate.criterion.Criterionインターフェースを慎重に実装します。
  1. パブリック クラス GenericStringArrayContainsCriterion extends LikeExpression {
  2. public GenericStringArrayContainsCriterion ( String propertyName、 String value ) {
  3. super ( propertyName、 "%" + WhitespaceEscapeUtil。escape ( value ) + "%" )
  4. }
  5. }
likeによる実装は、生産性の観点からはあまり効果的ではないことを明確に示します。 最適化のために、PostgreSQL 8.xの機能を使用して同じことを記述します。
  1. パブリック クラス PostgresStringArrayContainsCriterion は Criterion {
  2. プライベート 最終 文字列 propertyName ;
  3. プライベート 最終 文字列値。
  4. private final String TEMPLATE = "to_tsvector( 'simple'、{column})@@ plainto_tsquery( 'simple' ,?)" ;
  5. private static final char TAG_SEPARATOR = '' ;
  6. public PostgresStringArrayContainsCriterion ( String propertyName、 String value ) {
  7. これ 。 propertyName = propertyName ;
  8. これ 。 値 = WhitespaceEscapeUtil。 エスケープ (値) ;
  9. }
  10. public String toSqlString ( Criteria criteria、CriteriaQuery criteriaQuery ) throws HibernateException {
  11. StringHelperを返します。 replace ( TEMPLATE、 "{column}" 、criteriaQuery。getColumn ( criteria、propertyName ) ) ;
  12. }
  13. public TypedValue [ ] getTypedValues ( Criteria criteria、CriteriaQuery criteriaQuery ) throws HibernateException {
  14. return new TypedValue [ ] { new TypedValue ( Hibernate。STRING、value、EntityMode。POJO ) } ;
  15. }
  16. }
そして、「戦略」テンプレートを使用して、現在の方言に応じて実装を選択します。
  1. パブリック クラス StringArrayContainsCriterion は Criterion {
  2. プライベート 最終 文字列 propertyName ;
  3. プライベート 最終 文字列値。
  4. public StringArrayContainsCriterion ( String propertyName、 String value ) {
  5. これ 。 propertyName = propertyName ;
  6. これ 。 値 =値;
  7. }
  8. public String toSqlString ( Criteria criteria、CriteriaQuery criteriaQuery ) throws HibernateException {
  9. getStrategy ( criteriaQuery.getFactory ( ) 。 getDialect ( ) )を 返します。 toSqlString ( criteria、criteriaQuery ) ;
  10. }
  11. public TypedValue [ ] getTypedValues ( Criteria criteria、CriteriaQuery criteriaQuery ) throws HibernateException {
  12. getStrategy ( criteriaQuery.getFactory ( ) 。 getDialect ( ) )を 返します。 getTypedValues ( criteria、criteriaQuery ) ;
  13. }
  14. 公開基準getStrategy (方言方言) {
  15. if ( PostgreSQLDialectの方言インスタンス ) {
  16. 新しい PostgresStringArrayContainsCriterion ( propertyName、value )を 返し ます。
  17. } else {
  18. 新しい GenericStringArrayContainsCriterion ( propertyName、value )を 返し ます。
  19. }
  20. }
  21. }


まあ、それがすべてです。 これで、カスタムタイプを保存およびフィルタリングできます。

______________________
テキストは©SoftCoder.ruによってブログエディターで作成されます。


Source: https://habr.com/ru/post/J91434/


All Articles