@@ -249,39 +249,42 @@ Criteria applyScrollCriteria(Criteria criteria, @Nullable ScrollPosition positio
249
249
List <String > columns = new ArrayList <>(keys .keySet ());
250
250
List <Object > values = new ArrayList <>(keys .values ());
251
251
252
+ if (columns .isEmpty () || values .isEmpty ())
253
+ return criteria ;
254
+
252
255
Map <String , Sort .Direction > directions =
253
256
sort .stream ().collect (Collectors .toMap (Sort .Order ::getProperty , Sort .Order ::getDirection ));
254
257
255
- String primary = columns .get (0 );
256
- Object primaryValue = values .get (0 );
258
+ Sort .Direction dir = directions .getOrDefault (columns .get (0 ), Sort .DEFAULT_DIRECTION );
257
259
258
- Criteria primaryCompare ;
259
- Sort .Direction dir = directions .getOrDefault (primary , Sort .DEFAULT_DIRECTION );
260
+ Criteria scroll = buildKeysetCriteria (columns , values , keyset .scrollsForward (), dir );
260
261
261
- if (keyset .scrollsForward () ^ dir .isDescending ()) {
262
- primaryCompare = columns .size () != 1 ? Criteria .where (primary ).greaterThanOrEquals (primaryValue ) : Criteria .where (primary ).greaterThan (primaryValue );
263
- } else {
264
- primaryCompare = columns .size () != 1 ? Criteria .where (primary ).lessThanOrEquals (primaryValue ) : Criteria .where (primary ).lessThan (primaryValue );
265
- }
262
+ return criteria .and (scroll );
263
+ }
266
264
267
- if (columns .size () == 1 )
268
- return criteria .and (primaryCompare );
265
+ Criteria buildKeysetCriteria (List <String > columns , List <Object > values , boolean isForward , Sort .Direction dir ) {
266
+ if (columns .isEmpty ())
267
+ return Criteria .empty ();
269
268
270
- Criteria tupleCompare = null ;
271
- for (int i = 0 ; i < columns .size (); i ++) {
272
- Criteria orCriteria ;
273
- String col = columns .get (i );
274
- Object val = values .get (i );
269
+ String column = columns .get (0 );
270
+ Object value = values .get (0 );
275
271
276
- Sort .Direction colDir = directions .getOrDefault (col , dir );
277
- boolean asc = keyset .scrollsForward () ? colDir .isAscending () : colDir .isDescending ();
272
+ boolean isAscending = isForward ^ dir .isDescending ();
278
273
279
- orCriteria = asc ? Criteria .where (col ).greaterThan (val ) : Criteria .where (col ).lessThan (val );
274
+ Criteria gte = isAscending
275
+ ? Criteria .where (column ).greaterThanOrEquals (value )
276
+ : Criteria .where (column ).lessThanOrEquals (value );
280
277
281
- tupleCompare = (tupleCompare == null ) ? orCriteria : tupleCompare .or (orCriteria );
282
- }
278
+ Criteria gt = isAscending
279
+ ? Criteria .where (column ).greaterThan (value )
280
+ : Criteria .where (column ).lessThan (value );
281
+
282
+ if (columns .size () == 1 )
283
+ return gt ;
284
+
285
+ Criteria nested = buildKeysetCriteria (columns .subList (1 , columns .size ()), values .subList (1 , values .size ()), isForward , dir );
283
286
284
- return criteria .and (primaryCompare ). and ( tupleCompare );
287
+ return gte .and (gt . or ( nested ) );
285
288
}
286
289
287
290
SelectBuilder .SelectOrdered applyOrderBy (Sort sort , RelationalPersistentEntity <?> entity , Table table ,
0 commit comments