Java QueryDsl动态排序

Java QueryDsl动态排序,java,spring-data-jpa,querydsl,Java,Spring Data Jpa,Querydsl,我希望spring数据返回一个较小的dto类来代替我的完整实体 在QueryDsl和SpringDataJPA的帮助下,我试图构造一个查询EntityPath的服务,但返回了一个兼容的数据传输对象。我希望以动态方式构建此查询 <!-- language: java --> /** * @param type The dto class you want to query * @param ep The entitypath for the full cla

我希望spring数据返回一个较小的dto类来代替我的完整实体

在QueryDsl和SpringDataJPA的帮助下,我试图构造一个查询EntityPath的服务,但返回了一个兼容的数据传输对象。我希望以动态方式构建此查询

<!-- language: java -->    
/**
     * @param type The dto class you want to query
     * @param ep The entitypath for the full class (generated QClass)
     * @param pageRequest The spring data jpa domain pagerequest instance
     * @param predicate predicate generated by .getValue() on a BooleanExpression
     */
    @Override
    public Page<? extends DtoMarker> getPagedResultsForDto(Class<? extends DtoMarker> type, EntityPath<?> ep , PageRequest pageRequest, Predicate predicate) throws NoSuchFieldException, SecurityException{        

    List<Expression<?>> expressions = getExpressions(type, ep);

    JPAQuery query = new JPAQuery(em);
    query = query.from(ep).where(predicate);
            if (pageRequest != null) {
                query = query.limit(pageRequest.getPageSize()).offset(pageRequest.getOffset());                 
            }

    if (pageRequest.getSort() != null) {
        for (Sort.Order o : pageRequest.getSort()) {
            query = query.orderBy(toOrderSpecifier(o, ep));
        }
    }

    List<? extends DtoMarker> tuples = query.list(Projections.bean(type, expressions.toArray(new Expression[expressions.size()])));
    return new PageImpl<>(tuples, pageRequest, getCountTotalSizeForDto(type, ep, pageRequest, predicate));
}


private List<Expression<?>> getExpressions(Class<? extends DtoMarker> type,
        EntityPath<?> ep) {
    List<Expression<?>> expressions = new ArrayList<Expression<?>>();
    List<Field> fields = new ArrayList<Field>();
    for (Field field : type.getDeclaredFields()){
        fields.add(field);
    }
    for (Field field : type.getSuperclass().getDeclaredFields()){
        fields.add(field);
    }
    for (Field field : fields) {
        String generictype = field.getType().getSimpleName();

            if (generictype.equals("String")){
                expressions.add(new StringPath(ep, field.getName()));                   
            }
            if (generictype.equals("Boolean")) {
                expressions.add(new BooleanPath(ep, field.getName()));
            }
            if (generictype.equals("Long")) {
                expressions.add(new NumberPath<Long>(Long.class, ep, field.getName()));
            }
    }
    return expressions;
}

/**
*@param键入要查询的dto类
*@param ep完整类(生成的QClass)的entitypath
*@param pageRequest spring数据jpa域pageRequest实例
*@param谓词由.getValue()在布尔表达式上生成
*/
@凌驾
公共页面>表达式=获取表达式(类型,ep);
JPAQuery query=新的JPAQuery(em);
query=query.from(ep).where(谓词);
if(pageRequest!=null){
query=query.limit(pageRequest.getPageSize()).offset(pageRequest.getOffset());
}
if(pageRequest.getSort()!=null){
for(Sort.Order o:pageRequest.getSort()){
query=query.orderBy(toOrderSpecifier(o,ep));
}
}
列表>获取表达式(类ep){
列表>();
列表字段=新的ArrayList();
for(字段:type.getDeclaredFields()){
字段。添加(字段);
}
for(字段:type.getSuperclass().getDeclaredFields()){
字段。添加(字段);
}
用于(字段:字段){
字符串generictype=field.getType().getSimpleName();
if(generictype.equals(“字符串”)){
add(新的StringPath(ep,field.getName());
}
if(generictype.equals(“布尔”)){
add(新的BooleanPath(ep,field.getName());
}
if(generictype.equals(“Long”)){
add(新的NumberPath(Long.class、ep、field.getName());
}
}
返回表达式;
}
这非常有效,唯一的问题是我实现排序的方式。我通过以下方式将spring数据jpa排序转换为querydsl:

<!-- language: java -->
@SuppressWarnings({ "rawtypes", "unchecked" })
    private OrderSpecifier<?> toOrderSpecifier(Order order, EntityPath<?> ep) {

        ComparablePath<?> sortPropertyExpression = new ComparablePath(Comparable.class, ep, order.getProperty());       


        com.mysema.query.types.Order orderExpression = order.isAscending() ? com.mysema.query.types.Order.ASC
                : com.mysema.query.types.Order.DESC;

        return new OrderSpecifier(orderExpression, sortPropertyExpression);
    }

@SuppressWarnings({“rawtypes”,“unchecked”})
专用OrderSpecifier toOrderSpecifier(订单,EntityPath ep){
ComparablePath sortPropertyExpression=新的ComparablePath(Comparable.class,ep,order.getProperty());
com.mysema.query.types.Order orderExpression=Order.isascing()?com.mysema.query.types.Order.ASC
:com.mysema.query.types.Order.DESC;
返回新的OrderSpecifier(orderExpression、sortPropertyExpression);
}
但这有一个问题,字符串不能按ignorecase(=requirement)排序

也许这就是解决问题的途径

<!-- language: java -->
sortPropertyExpression = order.isIgnoreCase() ? Expressions.stringPath(order.getProperty()).lower() : Expressions.stringPath(order.getProperty()); 

sortPropertyExpression=order.isIgnoreCase()?Expressions.stringPath(order.getProperty()).lower():Expressions.stringPath(order.getProperty());
但它只适用于StringPath&对numberpath等给出了例外

有没有其他的想法我可以用来做动态排序