[英]Add PARTITION statement to query when using spring data JPA
take the example of the below SQL query以下面 SQL 查询为例
SELECT * FROM employees PARTITION (p0) WHERE name ='John'; SELECT * FROM employees PARTITION (p0) WHERE name ='John';
The above example can easily be written without "PARTITION (p0)" in Spring data JPA.在 Spring 数据 JPA 中没有“PARTITION (p0)”的情况下,上面的示例可以很容易地编写。 It gets a lot difficult when I need to add a partition.当我需要添加分区时会变得很困难。
One possible solution is to use native SQL.一种可能的解决方案是使用本机 SQL。 But, that is not an option for me because I have to use PaginationAndSorting and Criteriabuilder.但是,这不是我的选择,因为我必须使用 PaginationAndSorting 和 Criteriabuilder。 Any suggestions would be great.任何建议都会很棒。 Thanks.谢谢。
You can't do this with the Criteria API since it basically creates JPQL put the partition clause is part of SQL and there is no equivalent in JPQL.您不能使用标准 API 执行此操作,因为它基本上会创建 JPQL,而分区子句是 SQL 的一部分,并且在 JPQL 中没有等效项。
Since you seem to require to create the query dynamically I'd suggest you look into Querydsl and jOOQ to see if they support the partition clause or alternatively construct the SQL yourself using String concatenation.由于您似乎需要动态创建查询,我建议您查看 Querydsl 和 jOOQ 以查看它们是否支持分区子句,或者使用字符串连接自己构建 SQL 。 In that case you have to take care that you don't create a SQL injection vulnerability.在这种情况下,您必须注意不要创建 SQL 注入漏洞。
If all you need is actually pagination, that can be combined with with native @Query
annotations just fine.如果您实际上只需要分页,则可以将其与本机@Query
注释结合使用就可以了。
I finally found a way to do this.我终于找到了一种方法来做到这一点。
Need to create an interceptor to intercept all SQL queries and edit it as per requirement.需要创建一个拦截器来拦截所有 SQL 查询并根据需要进行编辑。
@Component
public class MyInterceptor extends EmptyInterceptor {
private static final long serialVersionUID = 1;
@Autowired
@Qualifier("PartitionContext")
private ThreadLocal<String> partitionContext;
@Override
public String onPrepareStatement(String sql) {
String partition = partitionContext.get();
if (partition != null) {
StringBuilder sb = new StringBuilder(sql);
sql = sb.insert(sql.indexOf(" where"), partition).toString();
partitionContext.remove();
}
return super.onPrepareStatement(sql);
}
}
We also need to register the interceptor like this.我们还需要像这样注册拦截器。
Component
public class MyInterceptorRegistration implements HibernatePropertiesCustomizer {
@Autowired
private MyInterceptor myInterceptor;
@Override
public void customize(Map<String, Object> hibernateProperties) {
hibernateProperties.put("hibernate.session_factory.interceptor", myInterceptor);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.