@@ -1,12 +1,13 @@
package com.lanyuanxiaoyao.service.template.jpa.service ;
import com.lanyuanxiaoyao.service.template.common.controller.Query ;
import com.lanyuanxiaoyao.service.template.common.entity.Page ;
import com.lanyuanxiaoyao.service.template.common.entity.Query ;
import com.lanyuanxiaoyao.service.template.common.exception.IdNotFoundException ;
import com.lanyuanxiaoyao.service.template.common.exception.NotCollectionException ;
import com.lanyuanxiaoyao.service.template.common.exception.NotComparableException ;
import com.lanyuanxiaoyao.service.template.common.exception.NotStringException ;
import com.lanyuanxiaoyao.service.template.common.helper.ObjectHelper ;
import com.lanyuanxiaoyao.service.template.common.service.Page ;
import com.lanyuanxiaoyao.service.template.common.service.QueryParser ;
import com.lanyuanxiaoyao.service.template.common.service.SimpleService ;
import com.lanyuanxiaoyao.service.template.jpa.entity.IdOnlyEntity ;
import com.lanyuanxiaoyao.service.template.jpa.entity.SimpleEntity ;
@@ -159,300 +160,6 @@ public abstract class SimpleServiceSupport<ENTITY extends SimpleEntity> implemen
) ;
}
/**
* 解析字段路径
* <p>
* 支持多级字段路径解析,使用"."分隔多级字段。
* 例如: "user.name" 表示实体的user属性的name字段。
* </p>
*
* @param root JPA Criteria查询根节点
* @param column 字段路径字符串
* @param <Y> 字段类型
* @return 返回字段路径对象
* @throws IllegalArgumentException 当字段路径为空时抛出
*/
private < Y > Path < Y > column ( Root < ENTITY > root , String column ) {
if ( ObjectHelper . isEmpty ( column ) ) {
throw new IllegalArgumentException ( " Column cannot be blank " ) ;
}
var columns = column . split ( " \\ . " ) ;
Path < Y > path = root . get ( columns [ 0 ] ) ;
for ( int i = 1 ; i < columns . length ; i + + ) {
path = path . get ( columns [ i ] ) ;
}
return path ;
}
/**
* 处理字段值
* <p>
* 对于枚举类型字段,将字符串值转换为对应的枚举值。
* 对于LocalDateTime类型字段, 将字符串转换为时间对象。
* 其他类型直接返回原值。
* </p>
*
* @param column 字段路径
* @param value 字段值
* @param <Y> 字段类型
* @return 处理后的字段值
* @throws IllegalArgumentException 当枚举类型字段的值不是字符串时抛出
*/
@SuppressWarnings ( { " unchecked " , " rawtypes " } )
private < Y > Object value ( Path < Y > column , Object value ) {
if ( ObjectHelper . isNull ( value ) ) {
return null ;
}
var javaType = column . getJavaType ( ) ;
if ( javaType . isEnum ( ) ) {
if ( value instanceof String enumName ) {
var enumType = ( Class < Enum > ) javaType ;
return Enum . valueOf ( enumType , enumName ) ;
} else {
throw new IllegalArgumentException ( " 枚举类型字段需要 String 类型的值 " ) ;
}
} else if ( javaType . isAssignableFrom ( LocalDateTime . class ) ) {
return LocalDateTime . parse ( String . valueOf ( value ) , DATE_TIME_FORMATTER ) ;
}
return value ;
}
/**
* 构建查询条件谓词列表
* <p>
* 根据Query.Queryable对象构建JPA Criteria查询的谓词列表。
* 支持多种查询条件类型,包括相等、不等、模糊匹配、范围查询等。
* </p>
*
* @param queryable 查询条件对象
* @param root JPA Criteria查询根节点
* @param query JPA Criteria查询对象
* @param builder JPA Criteria构建器
* @return 返回构建的谓词列表
*/
@SuppressWarnings ( " unchecked " )
private Predicate queryPredicates ( Query . Queryable queryable , Root < ENTITY > root , CriteriaQuery < ? > query , CriteriaBuilder builder ) {
var predicates = new ArrayList < Predicate > ( ) ;
if ( ObjectHelper . isNull ( queryable ) ) {
return null ;
}
if ( ObjectHelper . isNotEmpty ( queryable . nullEqual ( ) ) ) {
queryable . nullEqual ( ) . forEach ( column - > predicates . add ( builder . isNull ( column ( root , column ) ) ) ) ;
}
if ( ObjectHelper . isNotEmpty ( queryable . notNullEqual ( ) ) ) {
queryable . notNullEqual ( ) . forEach ( column - > predicates . add ( builder . isNotNull ( column ( root , column ) ) ) ) ;
}
if ( ObjectHelper . isNotEmpty ( queryable . empty ( ) ) ) {
queryable . empty ( ) . forEach ( column - > {
var path = this . < Collection < Object > > column ( root , column ) ;
checkCollection ( path , column ) ;
predicates . add ( builder . isEmpty ( path ) ) ;
} ) ;
}
if ( ObjectHelper . isNotEmpty ( queryable . notEmpty ( ) ) ) {
queryable . notEmpty ( ) . forEach ( column - > {
var path = this . < Collection < Object > > column ( root , column ) ;
checkCollection ( path , column ) ;
predicates . add ( builder . isNotEmpty ( path ) ) ;
} ) ;
}
if ( ObjectHelper . isNotEmpty ( queryable . equal ( ) ) ) {
queryable . equal ( ) . forEach ( ( column , value ) - > {
var path = column ( root , column ) ;
predicates . add ( builder . equal ( path , value ( path , value ) ) ) ;
} ) ;
}
if ( ObjectHelper . isNotEmpty ( queryable . notEqual ( ) ) ) {
queryable . notEqual ( ) . forEach ( ( column , value ) - > {
var path = column ( root , column ) ;
predicates . add ( builder . notEqual ( path , value ( path , value ) ) ) ;
} ) ;
}
if ( ObjectHelper . isNotEmpty ( queryable . like ( ) ) ) {
queryable . like ( ) . forEach ( ( column , value ) - > {
var path = this . < String > column ( root , column ) ;
checkString ( path , value , column ) ;
predicates . add ( builder . like ( path , value ) ) ;
} ) ;
}
if ( ObjectHelper . isNotEmpty ( queryable . notLike ( ) ) ) {
queryable . notLike ( ) . forEach ( ( column , value ) - > {
var path = this . < String > column ( root , column ) ;
checkString ( path , value , column ) ;
predicates . add ( builder . notLike ( path , value ) ) ;
} ) ;
}
if ( ObjectHelper . isNotEmpty ( queryable . contain ( ) ) ) {
queryable . contain ( ) . forEach ( ( column , value ) - > {
var path = this . < String > column ( root , column ) ;
checkString ( path , value , column ) ;
predicates . add ( builder . like ( path , " % " + value + " % " ) ) ;
} ) ;
}
if ( ObjectHelper . isNotEmpty ( queryable . notContain ( ) ) ) {
queryable . notContain ( ) . forEach ( ( column , value ) - > {
var path = this . < String > column ( root , column ) ;
checkString ( path , value , column ) ;
predicates . add ( builder . notLike ( path , " % " + value + " % " ) ) ;
} ) ;
}
if ( ObjectHelper . isNotEmpty ( queryable . startWith ( ) ) ) {
queryable . startWith ( ) . forEach ( ( column , value ) - > {
var path = this . < String > column ( root , column ) ;
checkString ( path , value , column ) ;
predicates . add ( builder . like ( path , value + " % " ) ) ;
} ) ;
}
if ( ObjectHelper . isNotEmpty ( queryable . notStartWith ( ) ) ) {
queryable . notStartWith ( ) . forEach ( ( column , value ) - > {
var path = this . < String > column ( root , column ) ;
checkString ( path , value , column ) ;
predicates . add ( builder . notLike ( path , value + " % " ) ) ;
} ) ;
}
if ( ObjectHelper . isNotEmpty ( queryable . endWith ( ) ) ) {
queryable . endWith ( ) . forEach ( ( column , value ) - > {
var path = this . < String > column ( root , column ) ;
checkString ( path , value , column ) ;
predicates . add ( builder . like ( path , " % " + value ) ) ;
} ) ;
}
if ( ObjectHelper . isNotEmpty ( queryable . notEndWith ( ) ) ) {
queryable . notEndWith ( ) . forEach ( ( column , value ) - > {
var path = this . < String > column ( root , column ) ;
checkString ( path , value , column ) ;
predicates . add ( builder . notLike ( path , " % " + value ) ) ;
} ) ;
}
if ( ObjectHelper . isNotEmpty ( queryable . great ( ) ) ) {
queryable . great ( ) . forEach ( ( column , value ) - > {
var path = this . < Comparable < Object > > column ( root , column ) ;
checkComparable ( path , value , column ) ;
predicates . add ( builder . greaterThan ( path , ( Comparable < Object > ) value ( path , value ) ) ) ;
} ) ;
}
if ( ObjectHelper . isNotEmpty ( queryable . less ( ) ) ) {
queryable . less ( ) . forEach ( ( column , value ) - > {
var path = this . < Comparable < Object > > column ( root , column ) ;
checkComparable ( path , value , column ) ;
predicates . add ( builder . lessThan ( path , ( Comparable < Object > ) value ( path , value ) ) ) ;
} ) ;
}
if ( ObjectHelper . isNotEmpty ( queryable . greatEqual ( ) ) ) {
queryable . greatEqual ( ) . forEach ( ( column , value ) - > {
var path = this . < Comparable < Object > > column ( root , column ) ;
checkComparable ( path , value , column ) ;
predicates . add ( builder . greaterThanOrEqualTo ( path , ( Comparable < Object > ) value ( path , value ) ) ) ;
} ) ;
}
if ( ObjectHelper . isNotEmpty ( queryable . lessEqual ( ) ) ) {
queryable . lessEqual ( ) . forEach ( ( column , value ) - > {
var path = this . < Comparable < Object > > column ( root , column ) ;
checkComparable ( path , value , column ) ;
predicates . add ( builder . lessThanOrEqualTo ( path , ( Comparable < Object > ) value ( path , value ) ) ) ;
} ) ;
}
if ( ObjectHelper . isNotEmpty ( queryable . inside ( ) ) ) {
queryable . inside ( )
. entrySet ( )
. stream ( )
. filter ( entry - > ObjectHelper . isNotEmpty ( entry . getValue ( ) ) )
. forEach ( entry - > predicates . add ( builder . in ( column ( root , entry . getKey ( ) ) ) . value ( entry . getValue ( ) ) ) ) ;
}
if ( ObjectHelper . isNotEmpty ( queryable . notInside ( ) ) ) {
queryable . notInside ( )
. entrySet ( )
. stream ( )
. filter ( entry - > ObjectHelper . isNotEmpty ( entry . getValue ( ) ) )
. forEach ( entry - > predicates . add ( builder . in ( column ( root , entry . getKey ( ) ) ) . value ( entry . getValue ( ) ) . not ( ) ) ) ;
}
if ( ObjectHelper . isNotEmpty ( queryable . between ( ) ) ) {
queryable . between ( ) . forEach ( ( column , value ) - > {
var path = this . < Comparable < Object > > column ( root , column ) ;
checkComparable ( path , value , column ) ;
predicates . add ( builder . between ( path , ( Comparable < Object > ) value ( path , value . start ( ) ) , ( Comparable < Object > ) value ( path , value . end ( ) ) ) ) ;
} ) ;
}
if ( ObjectHelper . isNotEmpty ( queryable . notBetween ( ) ) ) {
queryable . notBetween ( ) . forEach ( ( column , value ) - > {
var path = this . < Comparable < Object > > column ( root , column ) ;
checkComparable ( path , value , column ) ;
predicates . add ( builder . between ( path , ( Comparable < Object > ) value ( path , value . start ( ) ) , ( Comparable < Object > ) value ( path , value . end ( ) ) ) . not ( ) ) ;
} ) ;
}
return predicates . size ( ) = = 1
? predicates . get ( 0 )
: builder . and ( predicates . toArray ( Predicate [ ] : : new ) ) ;
}
/**
* 检查字段类型是否可比较
*
* @param path 字段路径
* @param value 比较值
* @param column 字段名称
* @throws NotComparableException 当字段类型不可比较时抛出
*/
private void checkComparable ( Path < ? > path , Object value , String column ) {
if ( ! ObjectHelper . isComparable ( path . getJavaType ( ) ) | | ! ObjectHelper . isComparable ( value ) ) {
throw new NotComparableException ( column ) ;
}
}
/**
* 检查区间值是否可比较
*
* @param path 字段路径
* @param value 区间对象
* @param column 字段名称
* @throws NotComparableException 当区间值不可比较时抛出
*/
private void checkComparable ( Path < ? > path , Query . Queryable . Between value , String column ) {
checkComparable ( path , value . start ( ) , column ) ;
checkComparable ( path , value . end ( ) , column ) ;
}
/**
* 检查字段类型是否为集合
*
* @param path 字段路径
* @param column 字段名称
* @throws NotCollectionException 当字段类型不是集合时抛出
*/
private void checkCollection ( Path < ? > path , String column ) {
if ( ! ObjectHelper . isCollection ( path . getJavaType ( ) ) ) {
throw new NotCollectionException ( column ) ;
}
}
/**
* 检查值是否为集合
*
* @param value 值对象
* @param column 字段名称
* @throws NotCollectionException 当值不是集合时抛出
*/
private void checkCollection ( Object value , String column ) {
if ( ! ObjectHelper . isCollection ( value ) ) {
throw new NotCollectionException ( column ) ;
}
}
/**
* 检查字段类型是否为字符串
*
* @param path 字段路径
* @param value 比较值
* @param column 字段名称
* @throws NotStringException 当字段类型不是字符串时抛出
*/
private void checkString ( Path < ? > path , Object value , String column ) {
if ( ! ObjectHelper . isString ( path . getJavaType ( ) ) | | ! ObjectHelper . isString ( value ) ) {
throw new NotStringException ( column ) ;
}
}
protected Predicate commonPredicates ( Root < ENTITY > root , CriteriaQuery < ? > query , CriteriaBuilder builder ) {
return null ;
}
@@ -487,7 +194,7 @@ public abstract class SimpleServiceSupport<ENTITY extends SimpleEntity> implemen
var result = repository . findAll (
( root , query , builder ) - > {
var predicate = commonPredicates ( root , query , builder ) ;
var queryPredicate = queryPredicates ( listQuery . query ( ) , root , query , builder ) ;
var queryPredicate = new JpaQueryParser < > ( root , query , builder ) . build ( listQuery . query ( ) ) ;
return ObjectHelper . isNull ( predicate )
? queryPredicate
: builder . and ( predicate , queryPredicate ) ;
@@ -586,4 +293,339 @@ public abstract class SimpleServiceSupport<ENTITY extends SimpleEntity> implemen
repository . deleteBatchByIds ( ids ) ;
}
}
@SuppressWarnings ( " unchecked " )
private static final class JpaQueryParser < ENTITY > extends QueryParser < Predicate > {
private final Root < ENTITY > root ;
@SuppressWarnings ( { " unused " , " FieldCanBeLocal " } )
private final CriteriaQuery < ? > query ;
private final CriteriaBuilder builder ;
private final List < Predicate > predicates = new ArrayList < > ( ) ;
private JpaQueryParser ( Root < ENTITY > root , CriteriaQuery < ? > query , CriteriaBuilder builder ) {
this . root = root ;
this . query = query ;
this . builder = builder ;
}
/**
* 解析字段路径
* <p>
* 支持多级字段路径解析,使用"."分隔多级字段。
* 例如: "user.name" 表示实体的user属性的name字段。
* </p>
*
* @param root JPA Criteria查询根节点
* @param column 字段路径字符串
* @param <Y> 字段类型
* @return 返回字段路径对象
* @throws IllegalArgumentException 当字段路径为空时抛出
*/
private < Y > Path < Y > column ( Root < ENTITY > root , String column ) {
if ( ObjectHelper . isEmpty ( column ) ) {
throw new IllegalArgumentException ( " Column cannot be blank " ) ;
}
var columns = column . split ( " \\ . " ) ;
Path < Y > path = root . get ( columns [ 0 ] ) ;
for ( int i = 1 ; i < columns . length ; i + + ) {
path = path . get ( columns [ i ] ) ;
}
return path ;
}
/**
* 处理字段值
* <p>
* 对于枚举类型字段,将字符串值转换为对应的枚举值。
* 对于LocalDateTime类型字段, 将字符串转换为时间对象。
* 其他类型直接返回原值。
* </p>
*
* @param column 字段路径
* @param value 字段值
* @param <Y> 字段类型
* @return 处理后的字段值
* @throws IllegalArgumentException 当枚举类型字段的值不是字符串时抛出
*/
@SuppressWarnings ( { " unchecked " , " rawtypes " } )
private < Y > Object value ( Path < Y > column , Object value ) {
if ( ObjectHelper . isNull ( value ) ) {
return null ;
}
var javaType = column . getJavaType ( ) ;
if ( javaType . isEnum ( ) ) {
if ( value instanceof String enumName ) {
var enumType = ( Class < Enum > ) javaType ;
return Enum . valueOf ( enumType , enumName ) ;
} else {
throw new IllegalArgumentException ( " 枚举类型字段需要 String 类型的值 " ) ;
}
} else if ( javaType . isAssignableFrom ( LocalDateTime . class ) ) {
return LocalDateTime . parse ( String . valueOf ( value ) , DATE_TIME_FORMATTER ) ;
}
return value ;
}
/**
* 检查字段类型是否可比较
*
* @param path 字段路径
* @param value 比较值
* @param column 字段名称
* @throws NotComparableException 当字段类型不可比较时抛出
*/
private void checkComparable ( Path < ? > path , Object value , String column ) {
if ( ! ObjectHelper . isComparable ( path . getJavaType ( ) ) | | ! ObjectHelper . isComparable ( value ) ) {
throw new NotComparableException ( column ) ;
}
}
/**
* 检查区间值是否可比较
*
* @param path 字段路径
* @param value 区间对象
* @param column 字段名称
* @throws NotComparableException 当区间值不可比较时抛出
*/
private void checkComparable ( Path < ? > path , Query . Queryable . Between value , String column ) {
checkComparable ( path , value . start ( ) , column ) ;
checkComparable ( path , value . end ( ) , column ) ;
}
/**
* 检查字段类型是否为集合
*
* @param path 字段路径
* @param column 字段名称
* @throws NotCollectionException 当字段类型不是集合时抛出
*/
private void checkCollection ( Path < ? > path , String column ) {
if ( ! ObjectHelper . isCollection ( path . getJavaType ( ) ) ) {
throw new NotCollectionException ( column ) ;
}
}
/**
* 检查值是否为集合
*
* @param value 值对象
* @param column 字段名称
* @throws NotCollectionException 当值不是集合时抛出
*/
private void checkCollection ( Object value , String column ) {
if ( ! ObjectHelper . isCollection ( value ) ) {
throw new NotCollectionException ( column ) ;
}
}
/**
* 检查字段类型是否为字符串
*
* @param path 字段路径
* @param value 比较值
* @param column 字段名称
* @throws NotStringException 当字段类型不是字符串时抛出
*/
private void checkString ( Path < ? > path , Object value , String column ) {
if ( ! ObjectHelper . isString ( path . getJavaType ( ) ) | | ! ObjectHelper . isString ( value ) ) {
throw new NotStringException ( column ) ;
}
}
@Override
protected void nullEqual ( Query . Queryable queryable ) {
queryable . nullEqual ( ) . forEach ( column - > predicates . add ( builder . isNull ( column ( root , column ) ) ) ) ;
}
@Override
protected void notNullEqual ( Query . Queryable queryable ) {
queryable . notNullEqual ( ) . forEach ( column - > predicates . add ( builder . isNotNull ( column ( root , column ) ) ) ) ;
}
@Override
protected void empty ( Query . Queryable queryable ) {
queryable . empty ( ) . forEach ( column - > {
var path = this . < Collection < Object > > column ( root , column ) ;
checkCollection ( path , column ) ;
predicates . add ( builder . isEmpty ( path ) ) ;
} ) ;
}
@Override
protected void notEmpty ( Query . Queryable queryable ) {
queryable . notEmpty ( ) . forEach ( column - > {
var path = this . < Collection < Object > > column ( root , column ) ;
checkCollection ( path , column ) ;
predicates . add ( builder . isNotEmpty ( path ) ) ;
} ) ;
}
@Override
protected void equal ( Query . Queryable queryable ) {
queryable . equal ( ) . forEach ( ( column , value ) - > {
var path = column ( root , column ) ;
predicates . add ( builder . equal ( path , value ( path , value ) ) ) ;
} ) ;
}
@Override
protected void notEqual ( Query . Queryable queryable ) {
queryable . notEqual ( ) . forEach ( ( column , value ) - > {
var path = column ( root , column ) ;
predicates . add ( builder . notEqual ( path , value ( path , value ) ) ) ;
} ) ;
}
@Override
protected void like ( Query . Queryable queryable ) {
queryable . like ( ) . forEach ( ( column , value ) - > {
var path = this . < String > column ( root , column ) ;
checkString ( path , value , column ) ;
predicates . add ( builder . like ( path , value ) ) ;
} ) ;
}
@Override
protected void notLike ( Query . Queryable queryable ) {
queryable . notLike ( ) . forEach ( ( column , value ) - > {
var path = this . < String > column ( root , column ) ;
checkString ( path , value , column ) ;
predicates . add ( builder . notLike ( path , value ) ) ;
} ) ;
}
@Override
protected void contain ( Query . Queryable queryable ) {
queryable . contain ( ) . forEach ( ( column , value ) - > {
var path = this . < String > column ( root , column ) ;
checkString ( path , value , column ) ;
predicates . add ( builder . like ( path , " % " + value + " % " ) ) ;
} ) ;
}
@Override
protected void notContain ( Query . Queryable queryable ) {
queryable . notContain ( ) . forEach ( ( column , value ) - > {
var path = this . < String > column ( root , column ) ;
checkString ( path , value , column ) ;
predicates . add ( builder . notLike ( path , " % " + value + " % " ) ) ;
} ) ;
}
@Override
protected void startWith ( Query . Queryable queryable ) {
queryable . startWith ( ) . forEach ( ( column , value ) - > {
var path = this . < String > column ( root , column ) ;
checkString ( path , value , column ) ;
predicates . add ( builder . like ( path , value + " % " ) ) ;
} ) ;
}
@Override
protected void notStartWith ( Query . Queryable queryable ) {
queryable . notStartWith ( ) . forEach ( ( column , value ) - > {
var path = this . < String > column ( root , column ) ;
checkString ( path , value , column ) ;
predicates . add ( builder . notLike ( path , value + " % " ) ) ;
} ) ;
}
@Override
protected void endWith ( Query . Queryable queryable ) {
queryable . endWith ( ) . forEach ( ( column , value ) - > {
var path = this . < String > column ( root , column ) ;
checkString ( path , value , column ) ;
predicates . add ( builder . like ( path , " % " + value ) ) ;
} ) ;
}
@Override
protected void notEndWith ( Query . Queryable queryable ) {
queryable . notEndWith ( ) . forEach ( ( column , value ) - > {
var path = this . < String > column ( root , column ) ;
checkString ( path , value , column ) ;
predicates . add ( builder . notLike ( path , " % " + value ) ) ;
} ) ;
}
@Override
protected void great ( Query . Queryable queryable ) {
queryable . great ( ) . forEach ( ( column , value ) - > {
var path = this . < Comparable < Object > > column ( root , column ) ;
checkComparable ( path , value , column ) ;
predicates . add ( builder . greaterThan ( path , ( Comparable < Object > ) value ( path , value ) ) ) ;
} ) ;
}
@Override
protected void less ( Query . Queryable queryable ) {
queryable . less ( ) . forEach ( ( column , value ) - > {
var path = this . < Comparable < Object > > column ( root , column ) ;
checkComparable ( path , value , column ) ;
predicates . add ( builder . lessThan ( path , ( Comparable < Object > ) value ( path , value ) ) ) ;
} ) ;
}
@Override
protected void greatEqual ( Query . Queryable queryable ) {
queryable . greatEqual ( ) . forEach ( ( column , value ) - > {
var path = this . < Comparable < Object > > column ( root , column ) ;
checkComparable ( path , value , column ) ;
predicates . add ( builder . greaterThanOrEqualTo ( path , ( Comparable < Object > ) value ( path , value ) ) ) ;
} ) ;
}
@Override
protected void lessEqual ( Query . Queryable queryable ) {
queryable . lessEqual ( ) . forEach ( ( column , value ) - > {
var path = this . < Comparable < Object > > column ( root , column ) ;
checkComparable ( path , value , column ) ;
predicates . add ( builder . lessThanOrEqualTo ( path , ( Comparable < Object > ) value ( path , value ) ) ) ;
} ) ;
}
@Override
protected void inside ( Query . Queryable queryable ) {
queryable . inside ( )
. entrySet ( )
. stream ( )
. filter ( entry - > ObjectHelper . isNotEmpty ( entry . getValue ( ) ) )
. forEach ( entry - > predicates . add ( builder . in ( column ( root , entry . getKey ( ) ) ) . value ( entry . getValue ( ) ) ) ) ;
}
@Override
protected void notInside ( Query . Queryable queryable ) {
queryable . notInside ( )
. entrySet ( )
. stream ( )
. filter ( entry - > ObjectHelper . isNotEmpty ( entry . getValue ( ) ) )
. forEach ( entry - > predicates . add ( builder . in ( column ( root , entry . getKey ( ) ) ) . value ( entry . getValue ( ) ) . not ( ) ) ) ;
}
@Override
protected void between ( Query . Queryable queryable ) {
queryable . between ( ) . forEach ( ( column , value ) - > {
var path = this . < Comparable < Object > > column ( root , column ) ;
checkComparable ( path , value , column ) ;
predicates . add ( builder . between ( path , ( Comparable < Object > ) value ( path , value . start ( ) ) , ( Comparable < Object > ) value ( path , value . end ( ) ) ) ) ;
} ) ;
}
@Override
protected void notBetween ( Query . Queryable queryable ) {
queryable . notBetween ( ) . forEach ( ( column , value ) - > {
var path = this . < Comparable < Object > > column ( root , column ) ;
checkComparable ( path , value , column ) ;
predicates . add ( builder . between ( path , ( Comparable < Object > ) value ( path , value . start ( ) ) , ( Comparable < Object > ) value ( path , value . end ( ) ) ) . not ( ) ) ;
} ) ;
}
@Override
protected Predicate build ( ) {
return predicates . size ( ) = = 1
? predicates . get ( 0 )
: builder . and ( predicates . toArray ( Predicate [ ] : : new ) ) ;
}
}
}