QueryDSL — преобразование предиката: изменение корневого пути и проверка структуры

Я использую эту замечательную библиотеку, но у меня есть проблема.

Я реализую шаблон DTO, поэтому я использую другой проект для автоматического преобразования EJB в DTO с использованием соглашений об именах.

Затем я хочу запросить DTO и получить реальный результат (запрос EJB).

Я реализовал QueryDSL с JPAAnnotationProcessor в своих ENTITIES и QuerydslAnnotationProcessor в своих DTO.

Например :

  • Пользователь объекта (длинный идентификатор, строковое имя пользователя, сайт сайта)
  • DTO UserDto (длинный идентификатор, строковое имя пользователя, строковое имя сайта)

Преобразование объектов хорошо, "siteName" автоматически соответствует "site.name".

Итак, я поставил запрос QueryDSL, например: userDto.id.gt(20).and(userDto.username.like("a%")).and(userDto.siteName.like("%b"));

Я ищу способ построить соответствующий запрос объекта

Единственная идея, которую я получил, состоит в том, чтобы:

  • Клонировать запрос
  • Измените путь «userDto» на «user»
  • Проверьте каждый предикат, чтобы узнать, существует ли свойство и соответствует ли тип

Любой способ сделать это или достичь моей цели?

Спасибо


person JamesPatageule    schedule 09.07.2014    source источник


Ответы (2)


Вам нужно будет преобразовать выражения в целом. С помощью пользовательского ReplaceVisitor вы можете, например, переопределить посещение (выражение пути, контекст @Nullable Void)

Общим способом замены пути было бы использование карты Map для определения замены:

if (map.contains(path)) {
    return map.get(path);
} else {
    return super.visit(path, context);
}

Вы можете использовать своего посетителя следующим образом:

Expression transformedExpression = expr.accept(visitor, null);
person Timo Westkämper    schedule 13.07.2014

Поскольку это все еще актуальная и недокументированная функциональность, и поскольку ответ Тимо, хотя и полезен, но очень загадочен, вот как это сделать:

Сначала расширьте ReplaceVisitor:

private class CustomReplaceVisior extends ReplaceVisitor<Void> {
    @Override
    public Expression<?> visit(Path<?> path, @Nullable Void context) {
        // The map Timo mentioned to transform paths:
        Map<Path<?>, Path<?>> map = Map.of(
            QUser.user.id, QUserDto.userDto.id,
            QUser.user.name, QUserDto.userDto.name
        );
        if (map.contains(path)) {
            return map.get(path);
        } else {
            return super.visit(path, context);
        }
    }
}

Затем используйте его следующим образом:

CustomReplaceVisior replaceVisitor = new CustomReplaceVisior();
Predicate userPredicate = QUser.user.id.eq(2).and(QUser.user.name.eq("Somename"));
Predicate userDtoPredicate = (Predicate) userPredicate.accept(replaceVisitor, null);
person Joakim    schedule 30.08.2019