1. 程式人生 > >Session中load/get方法的詳細區別

Session中load/get方法的詳細區別

根據對映配置和Select SQL得到的ResultSet,建立對應的資料物件。
將其資料物件納入當前Session實體管理容器(一級快取)。
執行Interceptor.onLoad方法(如果有對應的Interceptor)。
將資料物件納入二級快取。
如果資料物件實現了LifeCycle介面,則呼叫資料物件的onLoad方法。
返回資料物件。


/** *//**
  * load()方法的執行順序如下:
  * a):首先通過id在session快取中查詢物件,如果存在此id的物件,直接將其返回
  * b):在二級快取中查詢,找到後將 其返回。
  * c):如果在session快取和二級快取中都找不到此物件,則從資料庫中載入有此ID的物件
  * 因此load()方法並不總是導致SQL語句,只有快取中無此資料時,才向資料庫傳送SQL!  
  */


 /** *//**
  * 與get()的區別:
  * 1:在立即載入物件(當hibernate在從資料庫中取得資料組裝好一個物件後
  * 會立即再從資料庫取得資料此物件所關聯的物件)時,如果物件存在,
  * load()和get()方法沒有區別,都可以取得已初始化的物件;但如果當對
  * 象不存在且是立即載入時,使用get()方法則返回null,而使用load()則
  * 丟擲一個異常。因此使用load()方法時,要確認查詢的主鍵ID一定是存在
  * 的,從這一點講它沒有get方便!
  * 2:在延遲載入物件(Hibernate從資料庫中取得資料組裝好一個物件後,
  * 不會立即再從資料庫取得資料組裝此物件所關聯的物件,而是等到需要時,
  * 都會從資料庫取得資料組裝此物件關聯的物件)時,get()方法仍然使用
  * 立即載入的方式傳送SQL語句,並得到已初始化的物件,而load()方法則
  * 根本不傳送SQL語句,它返回一個代理物件,直到這個物件被訪問時才被
  * 初始化。
  */


get()----不支援LAZY

load()----支援LAZY


load和get一共是2個區別 先講第一個 延遲載入 
load是true而get是false
意 思就是 load採用的是延遲載入的方式 而get不是,hibernate思想是 既然這個方法支援延遲載入 他就認為這個物件一定在資料庫存在,在你 宣告 TFaq tfag2=(TFaq)sess.load(TFaq.class, 300); 這句時候,hibernate就幹了一件事 
1.查詢session快取
2.快取中沒有這個物件 就建立個代理
因為延遲載入需要代理來執行 所以就建立了個代理
ok 到此為止 這句話就幹了個這個 並沒有去資料庫互動查詢
當你使用這個物件 比如tfag2.getTfRtitle()或get方法時候
這個時候 hibernate就去查詢二級快取和資料庫,資料庫沒有這條資料 就丟擲異常
整個load方法呼叫結束 load沒什麼神奇 這就是他幹過所有的事情


load方法講完了 我在講一下get方法工作原理
因為hibernate規定get方法不能使用延遲載入 所以和load還是不一樣的
TFaq tfag2=(TFaq)sess.get(TFaq.class, 300);
在建立這條語句時候 我們看看hibernate幹了哪些事
1.get方法首先查詢session快取 (session快取就是hibernate的一級快取 這個概念大家應該清楚吧 )
2.get方法如果在session快取中找到了該id對應的物件,如果剛好該物件前面是被代理過的,如被load方法使用過,或者被其他關聯物件延遲載入過,那麼返回的還是原先的代理物件,而不是實體類物件。
3.如果該代理物件還沒有載入實體資料(就是id以外的其他屬性資料),那麼它會查詢二級快取或者資料庫來載入資料,但是返回的還是代理物件,只不過已經載入了實體資料。
(這個代理實際就是空的物件 並沒有去資料庫查詢得到的 我們叫代理物件,如果 去資料庫查詢了 返回到了這個物件 我們叫實體物件 就是這個物件真實存在)


我在總結性一句話這2者區別 
get方法首先查詢session快取,沒有的話查詢二級快取,最後查詢資料庫;反而load方法建立時首先查詢session快取,沒有就建立代理,實際使用資料時才查詢二級快取和資料庫



----我測試過:


在使用session.get方法後如果把session關閉的話,也會出現懶載入異常。


那麼只有在manytoone標籤裡配置 lazy="false"時異常才會解決。


也就是說上面轉載的第3條不是那麼正確:返回該代理物件不錯,但是如果該物件沒有載入實體資料,那麼也會在用到時才會載入,即不會立即查詢資料庫或者二級快取,那麼你現在把session關閉,這個對行啊沒有載入實體資料----才會出現懶載入異常。

相關推薦

Sessionload/get方法詳細區別

根據對映配置和Select SQL得到的ResultSet,建立對應的資料物件。 將其資料物件納入當前Session實體管理容器(一級快取)。 執行Interceptor.onLoad方法(如果有對應的Interceptor)。 將資料物件納入二級快取。 如果資料物件實現了LifeCycle介面,則呼叫資料物

Sessionload()和get()方法使用區別

2、當物件.hbm.xml配置檔案<class>元素的lazy屬性設定為true時,呼叫load()方法時則返回持久物件的代理類例項,此時的代理類例項是由執行時動態生成的類,該代理類例項包括原目標物件的所有屬性和方法,該代理類例項的屬性除了ID不為null外,所在屬性為null值,檢視日誌並沒有H

Hibernateget方法load方法有啥區別

1.執行get方法會立即載入物件,執行load不會立即載入,返回的是一個代理物件 下圖是兩個方法執行的結果,是相同的,這是因為c物件都被用到了 下圖是執行get方法,沒有用到c物件,但是卻傳送了sq

hibernate的loadget方法區別

1)當資料庫不存在對應ID資料時,呼叫load()方法將會丟擲ObjectNotFoundException異常,get()方法將返回null. 2)也就是延時載入的區別。load的方法預設要載入的物件是存在資料庫中的,返回的是一個代理物件而不是一個真正的類例項,當用到具體

HTTP方法GET和POST區別

HTTP1.1中的八個方法: 1.GET     請求獲取Request-URI所標識的資源 2.POST    在Request-URI所標識的資源後附加新的資料 3.HEAD    請求獲取由

Python函式和方法區別

在Python中函式和方法是有區別的。 區別一所處的位置:函式是直接寫檔案中而不是class中,方法是隻能寫在class中。 區別二定義的方式:  1.函式定義的方式 def關鍵字  然後接函式名 再是括號 括號裡面寫形參也可以省略不寫形參  def function

Java載入器ClassLoader使用方法詳細解析

ClassLoader 做什麼的? 顧名思義,它是用來載入 Class 的。它負責將 Class 的位元組碼形式轉換成記憶體形式的 Class 物件。位元組碼可以來自於磁碟檔案 .class,也可以是 jar 包裡的 .class,也可以來自遠端伺服器提供的位元組流,位元組碼的本質就是一個

Python字典get方法的使用

get方法是通過鍵來獲取對應的值。如果鍵不存在,會返回預設值None。也可以指定一個查詢失敗的值。 下邊通過例子來說明get方法的使用: #!/usr/bin/env python # -*- coding:utf-8 -*- a = {"Name": "Erich", "City":

jsload與onload的區別

在寫互動的時候,載入函式使onload還是load呢?糾結下,百度下,谷歌下。。。。。 趁機整理以防遺忘!! 且js中window.onload(function)等價於jquery中$(wind

ArrayList和LinkedListget方法底層實現

1.ArrayList的get方法  因為底層是陣列 直接通過下標獲得 2.LinkedList的get方法  因為底層是連結串列,連結串列沒有下標,需要迭代遍歷: if (index < (size >> 1)) { Nod

Object的equal()方法詳細與"=="

之前一直有點模糊的概念 equal()與==方法的區別!package com.yangfan.equal; public class Testequal { public static void main(String args[]) { Cat cat1 = n

SessionremoveAttribute()和invalidate()的區別

用於清空指定的session: request.getSession().removeAttribute("globe_user");  用於清空當前會話的全部的session: request.ge

post和get方法區別

HTTP 定義了與伺服器互動的不同方法,最基本的方法是 GET 和 POST。事實上 GET 適用於多數請求,而保留 POST 僅用於更新站點。根據 HTTP 規範,GET 用於資訊獲取,而且應該是 安全的和冪等的。所謂安全的意味著該操作用於獲取資訊而非修改資訊。換句話說,GET 請求一般不應產生副作用。

hibernate架構之sessiongetload方法區別

r.java one 升級版 數據庫 apache appenders 進行 方法 main hibernate是一個用於連接數據庫的升級版JDBC,與一般JDBC不同的是,hibernate架構是通過hql進行查找,通過session建立連接。其工作原理是:將實例分為瞬時

hibernate懶加載急加載的區別get方法load方的區別

() session 執行 語句 style 開啟 異常 方式 速度 懶加載是hibernate中的關聯關系對象的默認方式,懶加載也會先去查詢對象然後獲取對象的id, 當正真要對數據進行使用時才會正真寫sql語句。 懶加載的有效加載期是在session打開的時候,所以在我們

Hibernateget方法load方法區別

pub 機制 否則 on() color 檢索 不存在 bsp 數據庫查詢 1.從返回結果上對比: load方式檢索不到的話會拋出org.hibernate.ObjectNotFoundException異常; get方法檢索不到的話會返回null; 2.從檢索執行機制上對

在hibernate查詢資料的 sessiongetload區別:

* 第一點.傳送SQL的時機: * load這個方法採用了一個技術.lazy延遲載入(懶載入).真正使用這個物件的資料的時候.(物件的資料不包括主鍵). * get這個方法是立即檢索.當執行session.get()方法的時候,馬上傳送SQL語句查詢.   * 第二點.返回的物件:

hibernatesession.get( , )和session.load( , )的使用及區別

get(Class clazz,id)和load(Class clazz,id)都是用來根據主鍵的內容查詢資料庫中資料,並且返回相對應的類的物件 用法如下: public static void main(String[] args) { //讀取總的配置檔案 C

Hibernategetload方法區別

load方法可返回沒有載入實體資料的代理類例項,而get方法永遠返回有實體資料的物件。(對於load和get方法返回型別:好多書中都說:“get方法永遠只返回實體類”,實際上並不正確,get方法如果在session快取中找到了該id對應的物件,如果剛好該物件前面是被代理過的,如被load方法使用過,或者被其他

Hibernateget()和load()方法區別

在hibernate中我們知道如果要從資料庫中得到一個物件,通常有兩種方式,一種是通過session.get()方法,另一種就是通過session.load()方法,然後其實這兩種方法在獲得一個實體物件時是有區別的,在查詢效能上兩者是不同的。 一.load載入方式 當使用l