我尝试在Hibernate中优化数据库查询,但我发现了一个阻止程序:
<class name="SupportedLanguageVO" table="AR_SUPPORTED_LANG" >
<cache usage="read-only"/>
<id name="Id" type="java.math.BigInteger">
<column name="ID" sql-type="NUMBER(20)" not-null="true"/>
<generator class="assigned"/>
</id>
<property name="OrderSeq" type="java.math.BigInteger">
<column name="ORDER_SEQ" sql-type="NUMBER(20)" not-null="true"/>
</property>
<many-to-one name="Country" class="CountryVO" column="CTRY_CD_ID" cascade="none" >
<many-to-one name="Language" class="LanguageVO" column="LANG_CD" cascade="none" >
</class>
国家/地区的主键是CTRY_CD_ID
。如果我运行以下标准
Criteria crit = m_Session.createCriteria(SupportedLanguageVO.class);
crit.createCriteria("Country").add(Restrictions.eq("_CountryCode", p_countrycode));
crit.addOrder(Order.asc("OrderSeq"));
我可以看到,hibernate加入了ctry和AR_SUPPORTED_LANG表。 为什么? 运行
会更好select * from AR_SUPPORTED_LANG where ctry_cd_id=?
sql而不是
select * from AR_SUPPORTED_LANG inner join ctry .... where ctry_cd_id=?
我可以强制hibernate运行第一个查询吗?
答案 0 :(得分:1)
尝试为您的条件明确设置获取模式:
crit.setFetchMode("Country", FetchMode.SELECT);
答案 1 :(得分:1)
为什么呢?最好跑......
这不一定是真的,实际上在很大程度上取决于数据库如何优化其查询。一般来说,内部连接将更有效,因为它有机会大大减少搜索范围。当然,对于只有几十行的简单类型表,它看起来有点过分。添加几百万行,你会看到差异。
出于类似的原因,添加任何可以加入的查询提示通常是最佳的。例如(在HQL中重写您的查询):
from AR_SUPPORTED_LANG inner join ctry c where c.cd_id=?
......应该......
from AR_SUPPORTED_LANG inner join ctry c WITH c.cd_id=?
WITH子句是一种特定于HQL的方法,用于向JOIN语句添加AND子句。
答案 2 :(得分:1)
我认为你可以点缀它。 您应该直接在国家/地区对象上应用eq:
Criteria crit = m_Session.createCriteria(SupportedLanguageVO.class);
crit.add(Restrictions.eq("Country", p_country));
crit.addOrder(Order.asc("OrderSeq"));
这样,如果我记得很清楚,hibernate应该按照你想要的方式优化查询。但这意味着您需要国家/地区对象,而不仅仅是国家/地区代码。