如何使用 Criteria API 动态创建具有复杂基本子句的查询?
How can I dynamically create a query with a complex base clause using the Criteria API?
我正在尝试根据用户提交的搜索参数动态查询数据库。为了实现这种活力,我不再使用标准 JPA/Crud 存储库。但是,基本查询非常复杂。假设 HOUSE 和 WINDOW 都是实体 classes and,
select h.*
from HOUSE h join WINDOW w on h.id = w.house_id
where ((w.status in ('OPEN', 'HALF OPEN')) or
(w.status = 'CLOSED' and w.condition = 'GOOD') or
(w.status = 'CLOSED' and w.condition is null and w.refurbished_date between NOW() - INTERVAL 365 DAY AND NOW()) or
(w.status = 'CLOSED' and w.manufacture_date <> '1960-01-01 00:00:00' and w.refurbished_date between NOW() - INTERVAL 365 DAY AND NOW()))
(不是真正的查询,但它很好地体现了真实的查询)
这个查询没有改变。我只需要根据用户提供的内容附加 'AND' 子句。
我很难决定如何处理这个问题。我没有在网上找到任何建议我可以将上述 SQL 翻译成标准 API 的逻辑。
编辑:
到目前为止,我已经尝试使用纯 Java 动态创建查询并通过会话执行它。但是,返回的结果不会自动映射到我的实体 class(它们是对象类型),我不得不重写 ResultSetTransformer——一团糟!
我假设你的实际需求是动态查询,而不是Criteria API。如果是这种情况,您可以使用 FluentJPA 的 dynamic queries,它旨在为动态部分提供具有 "placeholders" 的类似模板的解决方案。
您也可以继续使用 JPA Repository 模式来实现。
请注意,我是 FluentJPA 库的维护者,但老实说,您的情况正是该库的设计目的。
您可以使用 spring-dynamic-jpa 编写查询模板。
查询模板将在执行前根据您调用方法时的参数构建成不同的查询字符串。
我正在尝试根据用户提交的搜索参数动态查询数据库。为了实现这种活力,我不再使用标准 JPA/Crud 存储库。但是,基本查询非常复杂。假设 HOUSE 和 WINDOW 都是实体 classes and,
select h.*
from HOUSE h join WINDOW w on h.id = w.house_id
where ((w.status in ('OPEN', 'HALF OPEN')) or
(w.status = 'CLOSED' and w.condition = 'GOOD') or
(w.status = 'CLOSED' and w.condition is null and w.refurbished_date between NOW() - INTERVAL 365 DAY AND NOW()) or
(w.status = 'CLOSED' and w.manufacture_date <> '1960-01-01 00:00:00' and w.refurbished_date between NOW() - INTERVAL 365 DAY AND NOW()))
(不是真正的查询,但它很好地体现了真实的查询)
这个查询没有改变。我只需要根据用户提供的内容附加 'AND' 子句。
我很难决定如何处理这个问题。我没有在网上找到任何建议我可以将上述 SQL 翻译成标准 API 的逻辑。
编辑: 到目前为止,我已经尝试使用纯 Java 动态创建查询并通过会话执行它。但是,返回的结果不会自动映射到我的实体 class(它们是对象类型),我不得不重写 ResultSetTransformer——一团糟!
我假设你的实际需求是动态查询,而不是Criteria API。如果是这种情况,您可以使用 FluentJPA 的 dynamic queries,它旨在为动态部分提供具有 "placeholders" 的类似模板的解决方案。
您也可以继续使用 JPA Repository 模式来实现。
请注意,我是 FluentJPA 库的维护者,但老实说,您的情况正是该库的设计目的。
您可以使用 spring-dynamic-jpa 编写查询模板。
查询模板将在执行前根据您调用方法时的参数构建成不同的查询字符串。