hibernate 使用Spring Data JPA时,向查询添加PARTITION语句

trnvg8h3  于 2023-01-13  发布在  Spring
关注(0)|答案(2)|浏览(263)

以下面的SQL查询为例
SELECT * FROM雇员**分区(p0)**WHERE名称=“约翰”;
在Spring Data JPA中,如果没有“PARTITION(p0)”,上面的例子很容易编写,但当我需要添加一个分区时,就变得非常困难了。
一个可能的解决方案是使用原生SQL。但是,这对我来说不是一个选择,因为我必须使用PaginationAndSorting和Criteriabuilder。任何建议都是很好的。谢谢。

8ehkhllq

8ehkhllq1#

您不能使用API执行此操作,因为它基本上创建了JPQL,而分区子句是SQL的一部分,并且在JPQL中没有等效项。
由于您似乎需要动态创建查询,我建议您查看一下Querydsl和jOOQ,看看它们是否支持分区子句,或者使用字符串连接自己构造SQL。在这种情况下,您必须注意不要创建SQL注入漏洞。
如果您实际上只需要分页,那么可以将其与原生@Query注解结合使用。

bis0qfac

bis0qfac2#

我终于找到了一个办法。
需要创建一个拦截器来拦截所有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);
    }
}

我们还需要像这样注册拦截器。

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);
    }
}

相关问题