- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
有没有办法通过 querydsl 别名对存储库查询结果进行排序?
到目前为止,我已经设法过滤,但排序结果出现错误:
org.springframework.data.mapping.PropertyReferenceException:找不到类型 User 的属性用户名!
要求:
GET/users?size=1&sort=username,desc
我的休息 Controller 方法:
@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
,但是那里使用的一些方法是包私有(private)的,所以我想也许我会进入错误的方向
最佳答案
我成功地创建了一个 PageableArgumentResolver
,并使用查询根类的类类型进行注释,并将别名注册表添加到我的通用存储库接口(interface)。
这个解决方案似乎是一种解决方法,但至少它有效;)
存储库:
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);
}
}
关于java - 如何按 querydsl 别名排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44949660/
我的 QueryDSL 给了我一个异常(exception): 2014-10-26 02:12:00,013 DEBUG [ExceptionsHandler] org.springframewo
我想在 QueryDSL 中表达以下(Oracle)查询: SELECT * FROM entity WHERE entity.created < (sysdate - entity.delayInD
我们已经使用 maven 插件在我们的项目中配置了 QueryDSL 的生成: com.mysema.maven apt-maven-p
我有一个实体,其中包含一个名为 date 的字段和一个名为 creationDate 的字段。第一个可以为空,后者不能为空。 现在我想获取特定时间范围内的所有项目。如果date不为空,则使用date。
我看到了 Querydsl 的示例,但我不明白其中的 QEmployee 是什么 QEmployee employee = QEmployee.employee; QEmployee e = new
我是 QueryDSL 的新手,并且能够在 WHERE-IN 子句中使用多列组合查询,如下面的查询: selec T1.COL1, T1.COL2, .... T1.COL10 from T1 whe
我正在使用 FilfetDto 构建动态查询如果用户填写了 UI 中的某些字段,则该字段将包含一些值,但不是全部。所以我必须测试每个属性以仅在填充(非空)字段上构建查询过滤: JPAQuery
我正在尝试创建一个 where 子句,它检查一个值是否存储在列中(在“Q”类中标识为 public final DateTimePath startDate = createDateTime(
如何在 queryDsl 中编写此查询 SELECT a.id, (SELECT count(*) FROM ancestors_table t where t.ancestors LIKE CONC
我正在使用 QueryDSL 将我的查询映射到我的 Bean 中: QAmbiente qitem=new QAmbiente("x"); SQLTemplates template = new My
我正在尝试使用 QueryDSL 计算平均日期差异。 我创建了 a small project以简化的方式演示我要完成的工作(真正的查询要复杂得多,有大量的连接/位置/排序子句)。我们有一个 Cust
我们有一个正在进行的项目,我们在其中使用 querydsl-jpa 进行查询。当我们部署产品的新版本时,它会在启动 hibernate 之前自动执行 sql 文件脚本来更新表。此脚本只是手动制作的 s
事情是这样的: 我一直在使用querydsl-jpa在我的项目中,代码生成从来都不是问题。我在maven中使用这个插件: com.mysema.maven ma
如何在 QueryDSL 中以以下形式表达 where 子句: WHERE (E1 AND E2) OR (E3 AND E4) E1..E4 是任意 bool 表达式。要点是在括号内开始查询,因此
我正在尝试使用此处描述的替代方法从groovy实体生成querydsl类http://www.querydsl.com/static/querydsl/2.7.3/reference/html/ch0
public class ProductDTO { public ProductDTO(final String name, final Boolean isBrandNew) { ... }
我正在尝试使用投影从实体及其具有的某些关系中提取数据。然而。投影的构造函数接受三个参数;一个集合,整数和另一个整数。如果我没有将集合作为参数,这一切都很好,但是一旦我添加了集合,我就会开始收到 S
我只想检查 - QueryDSL 版本 3.1.1。 - 是否仍然无法加入子查询,如这里的答案中所写: JPQL / QueryDSL: join subquery and get aliased c
使用 QueryDSL - 除了使用 . Between 之外,还有其他方法可以从时间戳中按日期选择行吗?像这样的查询: where convert(date, mytimestamp) = '201
看来在 Jpa QueryDsl 中我可以使用分页,如下所示: return new JPAQueryFactory(getEntityManager()) .selectFrom(entit
我是一名优秀的程序员,十分优秀!