Hibernate中outer-join與lazy關鍵字的使用- -

Hibernate中outer-join與lazy關鍵字的使用,解決大家的困惑。

<hibernate-mapping>
    <class  name="com.meagle.bo.Order"    table="Orders"    dynamic-update="false"   dynamic-insert="false" >
        <id  name="id"  column="Order_ID"   type="int"   unsaved-value="0">
            <generator class="native">
            </generator>
        </id>
        <set   name="orderLineItems"    table="OrderLineItem"    lazy="true"    inverse="true"   cascade="save-update"     sort="unsorted">
              <key   column="Order_ID" ></key>
              <one-to-many   class="com.meagle.bo.OrderLineItem" />
        </set>
        <property   name="userName"  type="string"  update="true"  insert="true"  access="property"
            column="UserName"
            not-null="true"
            unique="false"  />

        <property      name="total"    type="double"    update="true"   insert="true"  access="property"   column="Total"
            not-null="false"
            unique="false"
        />
    </class>

</hibernate-mapping>

<hibernate-mapping>
    <class    name="com.meagle.bo.OrderLineItem"    table="OrderLineItem"    dynamic-update="false"      dynamic-insert="false" >
        <id   name="id"   column="OrderLineItem_ID"   type="int"   unsaved-value="0">
            <generator class="native">
            </generator>
        </id>
        <many-to-one   name="order"   class="com.meagle.bo.Order"   cascade="none"  outer-join="auto"   update="true"
            insert="true"
            access="property"
            column="Order_ID" />

        <property  name="description"  type="string"  update="true"  insert="true"  access="property"  column="Description"      not-null="false"   unique="false" />

        <property  name="lineItemPrice"    type="double"    update="true"     insert="true"     access="property"
            column="LineItemPrice"
            not-null="false"
            unique="false"
        />
    </class>

</hibernate-mapping>

近來一直困惑與outer-join關鍵字,經過多次測試之後,現總結如下:

1、outer-join關鍵字(many-to-one的情況)

outer-join關鍵字有3個值,分別是true,false,auto,默認是auto。
true: 表示使用外連接抓取關聯的內容,這裏的意思是當使用load(OrderLineItem.class,"id")時,Hibernate只生成一條SQL語句將OrderLineItem與他的父親Order全部初始化。

select * from OrderLineItem o left join Order p on o.OrderId=p.OrderId  where o.OrderLineItem_Id=?

false:表示不使用外連接抓取關聯的內容,當load(OrderLineItem.class,"id")時,Hibernate生成兩條SQL語句,一條查詢OrderLineItem表,另一條查詢Order表。這樣的好處是可以設置延遲加載,此處要將Order類設置爲lazy=true。

select * from OrderLineItem o where o.OrderLineItem_Id=?
select * from Order p where p.OrderId=?

auto:具體是ture還是false看hibernate.cfg.xml中的配置

注意:如果使用HQL查詢OrderLineItem,如 from OrderLineItem o where o.id='id',總是不使用外部抓取,及outer-join失效。

2、outer-join(集合)

由於集合可以設置lazy="true",所以lazy與outer-join不能同時爲true,當lazy="true"時,outer-join將一直是false,如果lazy="false",則outer-join用法與1同

3、HQL語句會將POJO配置文件中的關聯一併查詢,即使在HQL語句中沒有明確join。

4、In HQL, the "fetch join" clause can be used for per-query specific outer join fetching. One important thing many people miss there, is that HQL queries will ignore the outer-join attribute you specified in your mapping. This makes it possible to configure the default loading behaviour of session.load() and session.get() and of objects loaded by navigating relationship. So if you specify

and then do
MyObject obj = session.createQuery("from MyObject").uniqueResult();
obj.getMySet().iterator().next();

you will still have an additional query and no outer-join. So you must explicily request the outer-join fetching:

MyObject obj = session.createQuery(
    "from MyObject mo left join fetch mo.mySet").uniqueResult();
obj.getMySet().iterator().next();

Another important thing to know is that you can only fetch one collection reference in a query. That means you can just use one fetch join. You can however fetch "one" references in addition, as this sample from the Hibernate Docs demonstrates:

from eg.Cat as cat
    inner join fetch cat.mate
    left join fetch cat.kittens

We have once considered lifting this limitation, but then decided against it, because using more than one fetch-join would be a bad idea generally: The generated ResultSet becomes huge and is a major performance loss.

So alltogether the "fetch join" clause is an important instrument Hibernate users should learn how to leverage, as it allows tuning the fetch behaviour of a certain use case.

5、join fetch 與 join 的區別

如果HQL使用了連接,但是沒有使用fetch關鍵字,則生成的SQL語句雖然有連接,但是並沒有取連接表的數據,還是需要單獨的sql取數據,也就是 select a,b,d...中沒有連接表的字段

6、如果集合被聲明爲lazy=true,在HQL中如果顯式的使用 join fetch 則延遲加載失效。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章