【问题标题】:How to sort by querydsl alias如何按querydsl别名排序
【发布时间】:2017-12-10 12:07:54
【问题描述】:

有没有办法通过 querydsl 别名对存储库查询结果进行排序?

到目前为止,我已经设法过滤,但排序结果出现错误:

org.springframework.data.mapping.PropertyReferenceException: No property username found for type User!

请求:

GET /users?size=1&sort=username,desc

我的休息控制器方法:

@GetMapping("/users")
public ListResult<User> getUsersInGroup(
        @ApiIgnore @QuerydslPredicate(root = User.class) Predicate predicate,
        Pageable pageable) {
    Page<User> usersInGroup =
            userRepository.findByGroup(CurrentUser.getGroup(), predicate, pageable);
    return new ListResult<>(usersInGroup);
}

我的仓库:

@Override
default void customize(QuerydslBindings bindings, QUser root) {
    bindings.including(root.account.login, root.account.firstName, root.account.lastName,
            root.account.phoneNumber, root.account.email, root.account.postalCode, root.account.city,
            root.account.address, root.account.language, root.account.presentationAlias);
    bindAlias(bindings, root.account.login, "username");
}

default Page<User> findByGroup(Group group, Predicate predicate, Pageable pageable) {
    BooleanExpression byGroup = QUser.user.group.eq(group);
    BooleanExpression finalPredicate = byGroup.and(predicate);
    return findAll(finalPredicate, pageable);
}

default void bindAlias(QuerydslBindings bindings, StringPath path, String alias) {
    bindings.bind(path).as(alias).first(StringExpression::likeIgnoreCase);
}

我也尝试在QuerydslPredicateArgumentResolver的基础上实现我自己的PageableArgumentResolver,但是那里使用的一些方法是包私有的,所以我想我可能走错了方向

【问题讨论】:

    标签: java spring spring-mvc jpa querydsl


    【解决方案1】:

    我成功创建了一个PageableArgumentResolver,并使用查询根类的类类型进行了注释,并将别名注册表添加到我的通用存储库接口。

    这个解决方案似乎是一种解决方法,但至少它有效;)

    存储库:

    public interface UserRepository extends PageableAndFilterableGenericRepository<User, QUser> {
    
    QDSLAliasRegistry aliasRegistry = QDSLAliasRegistry.instance();
    
    @Override
    default void customize(QuerydslBindings bindings, QUser root) {
        bindAlias(bindings, root.account.login, "username");
    }
    
    default void bindAlias(QuerydslBindings bindings, StringPath path, String alias) {
        bindings.bind(path).as(alias).first(StringExpression::likeIgnoreCase);
        aliasRegistry.register(alias, path);
    }
    

    别名注册表:

    public class QDSLAliasRegistry {
    
    private static QDSLAliasRegistry inst;
    
    public static QDSLAliasRegistry instance() {
        inst = inst == null ? new QDSLAliasRegistry() : inst;
        return inst;
    }
    
    private QDSLAliasRegistry() {
        registry = HashBiMap.create();
    }
    
    HashBiMap<String, Path<?>> registry;
    

    解析器:

    public class QDSLSafePageResolver implements PageableArgumentResolver {
    
    private static final String DEFAULT_PAGE = "0";
    private static final String DEFAULT_PAGE_SIZE = "20";
    private static final String PAGE_PARAM = "page";
    private static final String SIZE_PARAM = "size";
    private static final String SORT_PARAM = "sort";
    private final QDSLAliasRegistry aliasRegistry;
    
    public QDSLSafePageResolver(QDSLAliasRegistry aliasRegistry) {
        this.aliasRegistry = aliasRegistry;
    }
    
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return Pageable.class.equals(parameter.getParameterType())
                && parameter.hasParameterAnnotation(QDSLPageable.class);
    }
    
    @Override
    public Pageable resolveArgument(MethodParameter parameter,
                                    ModelAndViewContainer mavContainer,
                                    NativeWebRequest webRequest,
                                    WebDataBinderFactory binderFactory) {
    
        MultiValueMap<String, String> parameterMap = getParameterMap(webRequest);
    
        final Class<?> root = parameter.getParameterAnnotation(QDSLPageable.class).root();
        final ClassTypeInformation<?> typeInformation = ClassTypeInformation.from(root);
    
        String pageStr = Optional.ofNullable(parameterMap.getFirst(PAGE_PARAM)).orElse(DEFAULT_PAGE);
        String sizeStr = Optional.ofNullable(parameterMap.getFirst(SIZE_PARAM)).orElse(DEFAULT_PAGE_SIZE);
        int page = Integer.parseInt(pageStr);
        int size = Integer.parseInt(sizeStr);
        List<String> sortStrings = parameterMap.get(SORT_PARAM);
        if(sortStrings != null) {
            OrderSpecifier[] specifiers = new OrderSpecifier[sortStrings.size()];
    
            for(int i = 0; i < sortStrings.size(); i++) {
                String sort = sortStrings.get(i);
                String[] orderArr = sort.split(",");
                Order order = orderArr.length == 1 ? Order.ASC : Order.valueOf(orderArr[1].toUpperCase());
                specifiers[i] = buildOrderSpecifier(orderArr[0], order, typeInformation);
            }
    
            return new QPageRequest(page, size, specifiers);
        } else {
            return new QPageRequest(page, size);
        }
    }
    
    private MultiValueMap<String, String> getParameterMap(NativeWebRequest webRequest) {
        MultiValueMap<String, String> parameters = new LinkedMultiValueMap<String, String>();
    
        for (Map.Entry<String, String[]> entry : webRequest.getParameterMap().entrySet()) {
            parameters.put(entry.getKey(), Arrays.asList(entry.getValue()));
        }
        return parameters;
    }
    
    private OrderSpecifier<?> buildOrderSpecifier(String sort,
                                                  Order order,
                                                  ClassTypeInformation<?> typeInfo) {
    
    
        Expression<?> sortPropertyExpression = new PathBuilderFactory().create(typeInfo.getType());
        String dotPath = aliasRegistry.getDotPath(sort);
        PropertyPath path = PropertyPath.from(dotPath, typeInfo);
        sortPropertyExpression = Expressions.path(path.getType(), (Path<?>) sortPropertyExpression, path.toDotPath());
    
        return new OrderSpecifier(order, sortPropertyExpression);
    }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-22
      • 1970-01-01
      • 2015-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多