一 get load區別
1 User u=(User)session.get(User.class,id)方式 會直接獲取數據庫對象 沒有什麼代理 直接打印SQL語句
User u=(User)session.load(User.class,id)方式 會獲得一個代理對象 其中這個代理對象有一個ID屬性 其他屬性並沒有 在調用其他屬性時候 纔會全部加載 從數據庫查詢 發出SQL
User u=(User)load(User.class,101);//101在數據庫中不存在
u.getId()此處由於ID已經存在不會拋出異常
2
get方式加載 若數據庫沒有 則會返回Null
u.getName()會拋出空指針異常
load方式 如果數據庫中也沒有 返回的是一個代理對象並不是Null 次代理對象getId()是可以的 但是獲取其他屬性就會出現問題 拋出ObjectNotFoundException
3重要
我們在Dao層寫一個加載對象的load方法,返回一個加載的對象 在次方法裏面打開session 並在加載對象之後 關閉session(用finally)
在此方法中 如果調用load方法並返回代理對象(沒有get屬性) 那麼在上層service 或則view層調用對象get屬性之後會出現No session的異常 這是因爲我們在dao層 返回了一個代理對象之後 關閉了session 那麼在上層view 調用對象屬性getXXX就會去數據庫查詢 但此時session已經關閉 因此沒有session
解決方法:1 在Dao中使用get方法代替load方法 dao中直接返回完整的對象 但性能受影響
2 通過threaLocal把session放在表示層 session在表示層打開 使用完DAO後 在表示層關閉 (未實踐) spring 有個opensession in view的模式就是採用這種方法