У меня есть еще одно общее решение, которое должно работать для каждого Критерии запроса:
использовать стандартный комментарий и гибернации перехватчик изменения конечной SQL в базе данных.
(Я использовал его с Hibernate 3.3, но должен использоваться для каждой версии, регистрация Interceptor может быть разной.)
в запросе использования кода:
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, но следует легко настраивать для каждой СУБД.
Возможно, вы можете/должны создать константу для маркера подсказки «$ HINT $».
Ведение журнала должно быть выполнено (так что вы можете легко увидеть правильный вызов перехватчика), я оставил его выше для простоты.
Перехватчик должен быть зарегистрирован. Весной это делается в 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 Docs):
Сеанс-Scoped перехватчик указывается, когда сеанс открыт используя один из перегруженных SessionFactory .openSession() прием перехватчика.
Session session = sf.openSession(new HibernateEntityInterceptor());
SessionFactory-Scoped Перехватчик регистрируются с объектом конфигурации перед построением SessionFactory. Если не открыто сеанс с явным указанием использования перехватчика, то передаваемый перехватчик будет применен ко всем сеансам, открытым из этого SessionFactory. Перехватчики SessionFactory должны быть потоками безопасным. Убедитесь, что вы не сохраняете состояния, зависящие от сеанса, так как в течение нескольких сеансов несколько сеансов будут использовать этот перехватчик потенциально одновременно.
new Configuration().setInterceptor(new HibernateEntityInterceptor());
результат действительно будет пользователь лицом. –
сам запрос правильный, как есть. поскольку он генерируется динамически, его нельзя оптимизировать вручную, он различен для каждого поискового запроса. –