gpt4 book ai didi

java - 如何将 "Optimizer hint"插入到 Hibernate 条件 api 查询

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:04:37 25 4
gpt4 key购买 nike

我有一个使用条件 api 动态组合在一起的 hibernate 查询。如果按原样执行,它会生成非常慢的查询。

但我注意到,如果我在查询前加上/*+ FIRST_ROWS(10) */,它们的速度会提高大约 1000%。我如何使用标准 api 执行此操作?

我尝试了 criteria.setComment(..),但这似乎被忽略了。

在 hibernate 文档中,3.4.1.7。提到了查询提示,但它明确指出:“请注意,这些不是 SQL 查询提示”

查询的结果将被分页,所以在 99% 的情况下我会显示结果 1-10。

最佳答案

我有另一个通用解决方案,应该适用于每个条件查询:
使用标准注释和 Hibernate 拦截器将最终 SQL 更改为数据库。
(我在 Hibernate 3.3 中使用它,但应该适用于每个版本,拦截器的注册可能不同。)

在您的查询代码中使用:

criteria.setComment("$HINT$ push_pred(viewAlias)");

写一个拦截器来改变SQL文本(这个使用commons.lang3.StringUtils):

public class HibernateEntityInterceptor extends EmptyInterceptor {

@Override
public String onPrepareStatement(String sql) {
if (sql.startsWith("/* $HINT$")) {
String hintText = StringUtils.substringBetween(sql, "/* $HINT$", "*/");
sql = sql.replaceFirst("select ", "select /*+" + hintText + "*/ ");
}
return sql;
}

以上是针对 Oracle 的,但应该可以针对每个 DBMS 轻松调整。
也许你可以/应该为提示标记“$HINT$”创建一个常量。
日志记录也应该完成(这样你就可以很容易地看到拦截器的正确调用),为了简单起见,我在上面省略了它。

拦截器必须注册。在 Spring 中,这是在 applicationContext.xml 中完成的:

<bean id="entityListener" class="your.package.HibernateEntityInterceptor"/>

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="entityInterceptor" ref="entityListener"/>
[...]

或者(从 Hibernate 3.3 文档复制):

A Session-scoped interceptor is specified when a session is opened using one of the overloaded SessionFactory.openSession() methods accepting an Interceptor.

Session session = sf.openSession( new HibernateEntityInterceptor() );

A SessionFactory-scoped interceptor is registered with the Configuration object prior to building the SessionFactory. Unless a session is opened explicitly specifying the interceptor to use, the supplied interceptor will be applied to all sessions opened from that SessionFactory. SessionFactory-scoped interceptors must be thread safe. Ensure that you do not store session-specific states, since multiple sessions will use this interceptor potentially concurrently.

new Configuration().setInterceptor( new HibernateEntityInterceptor() );

关于java - 如何将 "Optimizer hint"插入到 Hibernate 条件 api 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1327503/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com