Created
May 31, 2016 11:22
-
-
Save dmitrygusev/1ff2d8f6d6f363595b73b581016c7733 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.ArrayList; | |
import java.util.List; | |
import org.apache.commons.lang3.tuple.Pair; | |
import com.mysema.query.BooleanBuilder; | |
import com.mysema.query.types.Expression; | |
import com.mysema.query.types.Order; | |
import com.mysema.query.types.Predicate; | |
import com.mysema.query.types.expr.ComparableExpression; | |
import com.mysema.query.types.expr.NumberExpression; | |
public class QueryHelper | |
{ | |
/** | |
* Implementing pagination with seek method | |
* http://use-the-index-luke.com/no-offset | |
*/ | |
public static PredicateDecorator getSeekPredicate(List<Pair<Order, Expression<?>>> fields, List<Comparable<?>> values) | |
{ | |
// where f1 < a | |
// or (f1 = a and f2 < b) | |
// or (f1 = a and f2 = b and f3 < c) | |
return predicate -> { | |
List<Predicate> expressions = new ArrayList<>(); | |
for (int i = 0; i < fields.size(); i++) | |
{ | |
Expression<?> left = fields.get(i).getValue(); | |
Comparable<?> right = values.get(i); | |
BooleanBuilder condition = new BooleanBuilder( | |
fields.get(i).getKey() == Order.DESC | |
? lt(left, right) | |
: gt(left, right)); | |
for (int j = 0; j < fields.size(); j++) | |
{ | |
Expression<?> field = fields.get(j).getValue(); | |
Comparable<?> value = values.get(j); | |
if (j < i) | |
{ | |
condition.and(eq(field, value)); | |
} | |
else | |
{ | |
expressions.add(condition); | |
break; | |
} | |
} | |
} | |
predicate.andAnyOf(expressions.toArray(new Predicate[0])); | |
}; | |
} | |
@SuppressWarnings({ "unchecked" }) | |
private static <T extends Comparable<?>, A extends Number & Comparable<Number>> Predicate lt(Expression<?> left, Comparable<?> right) | |
{ | |
if (left instanceof ComparableExpression) | |
{ | |
return ((ComparableExpression<T>) left).lt((T) right); | |
} | |
if (left instanceof NumberExpression) | |
{ | |
return ((NumberExpression<A>) left).lt((A) right); | |
} | |
throw new IllegalArgumentException(String.valueOf(left)); | |
} | |
@SuppressWarnings({ "unchecked" }) | |
private static <T extends Comparable<?>, A extends Number & Comparable<Number>> Predicate gt(Expression<?> left, Comparable<?> right) | |
{ | |
if (left instanceof ComparableExpression) | |
{ | |
return ((ComparableExpression<T>) left).gt((T) right); | |
} | |
if (left instanceof NumberExpression) | |
{ | |
return ((NumberExpression<A>) left).gt((A) right); | |
} | |
throw new IllegalArgumentException(String.valueOf(left)); | |
} | |
@SuppressWarnings({ "unchecked" }) | |
private static <T extends Comparable<?>, A extends Number & Comparable<Number>> Predicate eq(Expression<?> left, Comparable<?> right) | |
{ | |
if (left instanceof ComparableExpression) | |
{ | |
return ((ComparableExpression<T>) left).eq((T) right); | |
} | |
if (left instanceof NumberExpression) | |
{ | |
return ((NumberExpression<A>) left).eq((A) right); | |
} | |
throw new IllegalArgumentException(String.valueOf(left)); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import com.mysema.query.jpa.JPQLQuery; | |
import com.mysema.query.jpa.impl.JPAQuery; | |
import com.mysema.query.types.Expression; | |
import com.mysema.query.types.Order; | |
import org.joda.time.DateTime; | |
// ... | |
DateTime after = ...; | |
Long lastId = ...; | |
// ... | |
List<Pair<Order, Expression<?>>> fields = new ArrayList<>(); | |
List<Comparable<?>> values = new ArrayList<>(); | |
if (after != null) | |
{ | |
fields.add(Pair.of(Order.ASC, myEntity.createdAt)); | |
values.add(after.toDate()); | |
} | |
if (lastId != null) | |
{ | |
fields.add(Pair.of(Order.ASC, myEntity.id)); | |
values.add(lastId); | |
} | |
JPQLQuery query = builder | |
.decorate(QueryHelper.getSeekPredicate(fields, values)) | |
.build() | |
.orderBy(myEntity.createdAt.asc(), myEntity.id.asc()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment