简体   繁体   English

是否可以使用原始 SQL 字符串创建 QueryDSL 谓词?

[英]Is it possible to create a QueryDSL Predicate with a String of raw SQL?

I have a Java, GraphQL, Hibernate, PostgreSQL, QueryDSL application that queries a very large PostgreSQL table with over 275 columns.我有一个 Java、GraphQL、Hibernate、PostgreSQL、QueryDSL 应用程序,它查询一个超过 275 列的非常大的 PostgreSQL 表。

I've created a GraphQL schema with the 25 most popular columns as query-able fields.我创建了一个 GraphQL 模式,其中包含 25 个最流行的列作为可查询字段。 I'd like to add a generic "field" input type that consists of a name (the db column name + "_" + operation (like gte, gt, contains, etc.) and a value (the value the user is searching for).我想添加一个通用的“字段”输入类型,它由一个名称(db 列名称 +“_”+ 操作(如 gte、gt、contains 等)和一个值(用户正在搜索的值)组成为了)。

So when the user (in GraphiQL) enters something like (field:{name:"age_gt", value:"50"}) as a search input to the GraphQL query, I can come up with: "age > 50".因此,当用户(在 GraphiQL 中)输入类似 (field:{name:"age_gt", value:"50"}) 作为 GraphQL 查询的搜索输入时,我可以想出:“age > 50”。

All that works fine, but when it's time to create the Predicate and add it to the whole query ( booleanBuilder.and(new Predicate) ), I cannot figure out how to create a Predicate that just contains a raw String of SQL ("age > 50").一切正常,但是当需要创建 Predicate 并将其添加到整个查询( booleanBuilder.and(new Predicate) )时,我无法弄清楚如何创建一个只包含原始 SQL 字符串的 Predicate(“age > 50 英寸)。

I've created several Predicates the "right" way using my entity POJO tied to Hibernate and the jpa generated "Q" object.我已经使用绑定到 Hibernate 的实体 POJO 和 jpa 生成的“Q”对象以“正确”的方式创建了几个谓词。 But I need the ability to add one or more Predicates that are just a String of SQL.但我需要能够添加一个或多个只是 SQL 字符串的谓词。 I'm not even sure if the ability exists, the documentation for QueryDSL Predicates is non-existent.我什至不确定这种能力是否存在,QueryDSL Predicates 的文档不存在。

I'm thinking PredicateOperation() might be the answer, but again, no documentation and I cannot find any examples online.认为PredicateOperation() 可能是答案,但同样,没有文档,我也找不到任何在线示例。

My apologies for not posting code, all my stuff is behind a firewall on a different network so there's no cut and paste to my internet machine.我很抱歉没有发布代码,我所有的东西都在不同网络上的防火墙后面,所以没有剪切和粘贴到我的互联网机器上。

In Hibernate its possible to inject arbitrary SQL using custom functions or the FUNCTION -function (introduced in JPA 2.1).在 Hibernate 中,可以使用自定义函数或FUNCTION函数(在 JPA 2.1 中引入)注入任意 SQL。 In QueryDSL its possible to inject arbitrary JPQL/HQL through TemplateExpression s.在 QueryDSL 中,可以通过TemplateExpression注入任意 JPQL/HQL。 Combined you get:结合你得到:

Expressions.numberTemplate("FUNCTION('SUM', {0}), x) 

However, age > 50 as expression is probably valid JPQL as well, so one can just write:但是, age > 50作为表达式也可能是有效的 JPQL,所以可以这样写:

Expressions.numberTemplate("SUM(age)")

Either way, its probably best to create a visitor that traverses the GraphQL query and creates the proper expression in QueryDSL, as TemplateExpressions are prone to SQL injection.无论哪种方式,最好创建一个遍历 GraphQL 查询并在 QueryDSL 中创建正确表达式的访问者,因为TemplateExpressions容易受到 SQL 注入。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM