druid的java占位符条件查询,QueryDSL 查询条件的序列化与反序列化

本方法仅适用于 JPQL

构造查询条件并序列化到文本字符串

QueryDSL 提供了 com.querydsl.core.types.Visitor 以访问 DSL 结点,在此基础上提供了 com.querydsl.core.support.SerializerBase 以序列化 DSL,该接口对应 JPQL 的实现为 com.querydsl.jpa.JPQLSerializer.

主要用到的方法:

com.querydsl.core.support.SerializerBase#handle(com.querydsl.core.types.Expression>) 用以序列化条件 ( com.querydsl.core.types.Predicate ).

首先构造一个查询条件:

final Predicate predicate = QEduAction.eduAction.id.eq(2L)

.and(QEduAction.eduAction.name.like("%:GetCurrentTime"));

然后以 HQL 风格序列化到文本字符串:

JPQLSerializer jpqlSerializer = new JPQLSerializer(new HQLTemplates());

jpqlSerializer.handle(predicate);

String jpql = jpqlSerializer.toString();

// eduAction.id = ?1 and eduAction.name like ?2 escape '!'

com.querydsl.jpa.JPQLTemplates 的默认实现有很多个,针对项目选择,这里使用 com.querydsl.jpa.HQLTemplates .

关于查询条件序列化时丢失参数的问题

由于此法本质上是将查询条件序列化为模板,因此参数并不会跟着序列化.

如果需要解析出参数也不是不行,通过构造 com.querydsl.core.QueryMetadata 来获取 com.querydsl.core.types.PredicateOperation 并遍历其 args 节点,但是这里就需要分辨节点上是 Path 还是常量值,这部分涉及到的问题比较多,简单粗暴的办法则是直接提前构造参数列表.

List args = new ArrayList<>();

args.put(2L);

args.put("%s:GetCurrentTime");

final Predicate predicate = QEduAction.eduAction.id.eq((Long) args.get(0))

.and(QEduAction.eduAction.name.like((String) args.get(1));

然后将参数列表也序列化,这个就很容易了,直接转成 JSON 即可.

反序列化查询条件

核心点在于使用 com.querydsl.core.types.dsl.Expressions#booleanTemplate(java.lang.String, java.lang.Object...) 来通过字符串构造模板后生成查询条件.

int argIndex = 0;

StringBuilder stringBuilder = new StringBuilder();

// 由于模板使用的参数占位符是 {#index} 而不是 HQL 的 ?#index,因此这里需要转换一下.

final String[] split = jpql.split("\\?\\d+");

for (int i = 0; i < split.length; i++) {

if (i == split.length - 1) {

continue;

}

stringBuilder.append(String.format("%s{%s}", split[i], argIndex++));

}

jpql = stringBuilder.toString();

// eduAction.id = {0} and eduAction.name like {1}

其实这一步可以直接在序列化后顺便做了.

直接作为查询条件使用

new JPAQueryFactory(entityManager.getEntityManager())

.select(QEduAction.eduAction)

.from(QEduAction.eduAction)

.where(

Expressions.booleanTemplate(jpql, 2L, "%:GetCurrentTime")

);

参数列表从前面生成的 JSON 反序列化而来.

作为附加查询条件使用

final BooleanTemplate booleanTemplate = Expressions.booleanTemplate(jpql, 2L, "%:GetCurrentTime");

final JPAQuery query = new JPAQueryFactory(entityManager.getEntityManager())

.select(QEduAction.eduAction)

.from(QEduAction.eduAction)

.where(QEduAction.eduAction.policies.isEmpty());

query.getMetadata().addWhere(booleanTemplate);

生成的 HQL 为:

select eduAction

from EduAction eduAction

where eduAction.policies is empty and eduAction.id = ?1 and eduAction.name like ?2

b739ec46bb5c46d9c0aa4ce35ba1ea56.png

关于找一找教程网

本站文章仅代表作者观点,不代表本站立场,所有文章非营利性免费分享。

本站提供了软件编程、网站开发技术、服务器运维、人工智能等等IT技术文章,希望广大程序员努力学习,让我们用科技改变世界。

[QueryDSL 查询条件的序列化与反序列化]http://www.zyiz.net/tech/detail-99458.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值