一、什麼是ORM?
物件關聯映射(Object-Relational Mapping,簡稱ORM)是一種為了解決程式的物件導向模型與資料庫的關聯式模型互不符問題的技術;
簡單的說,ORM是透過使用描述物件和資料庫之間映射的元資料(在Java中可以用XML或註解),將程式中的物件自動持久化到關聯式資料庫中或將關聯式資料庫表中的行轉換成Java對象,其本質上就是將資料從一種形式轉換到另外一種形式。
二、Hibernate中SessionFactory是執行緒安全的嗎? Session是線程安全的嗎(兩個線程能夠共享同一個Session嗎)?
SessionFactory對應Hibernate的一個資料儲存的概念,它是執行緒安全的,可以被多個執行緒並發存取。 SessionFactory一般只會在啟動的時候建置。對於應用程序,最好將SessionFactory透過單例模式進行封裝以便於存取。
(學習影片推薦:java影片教學)
Session是一個輕量級非執行緒安全的物件(執行緒間不能共用session),它表示與資料庫進行互動的一個工作單元。 Session是由SessionFactory創建的,在任務完成之後它會關閉。 Session是持久層服務對外提供的主要介面。
Session會延遲取得資料庫連線(也就是在需要的時候才會取得)。為了避免創建太多的session,可以使用ThreadLocal將session和當前線程綁定在一起,這樣可以讓同一個線程獲得的總是同一個session。 Hibernate 3中SessionFactory的getCurrentSession()方法就可以做到。
三、Session的save()、update()、merge()、lock()、saveOrUpdate()和persist()方法分別是做什麼的?有什麼區別?
Hibernate的物件有三種狀態:瞬時態(transient)、持久態(persistent)和遊離態(detached)。
瞬時態的實例可以透過呼叫save()、persist()或saveOrUpdate()方法變成持久性;
遊離態的實例可以透過呼叫update()、saveOrUpdate()、 lock()或replicate()變成持久態。 save()和persist()將會引發SQL的INSERT語句,而update()或merge()會引發UPDATE語句。
save()和update()的差別在於一個是將瞬時態物件變成持久態,一個是將遊離態物件變成持久態。 merge()方法可以完成save()和update()方法的功能,它的意圖是將新的狀態合併到現有的持久化物件上或建立新的持久化物件。
對於persist()方法,按照官方文件的說明:
1、persist()方法把一個瞬時態的實例持久化,但是並不保證標識符被立刻填入到在持久化實例中,標識符的填入可能被推遲到flush的時間;
2、persist()方法保證當它在一個事務外部被調用的時候並不觸發一個INSERT語句,當需要封裝一個長會話流程的時候,persist()方法是很有必要的;
(推薦教學:java快速入門)
3、save()方法不保證第2條,它要回傳標識符,所以它會立即執行INSERT語句,不管是在事務內部還是外部。至於lock()方法和update()方法的區別,update()方法是把一個已經更改過的脫管狀態的對象變成持久狀態;lock()方法是把一個沒有更改過的脫管狀態的對象變成持久狀態。
四、闡述Session載入實體物件的過程
1、Session在呼叫資料庫查詢功能之前,首先會在一級快取中透過實體類型和主鍵進行查找,如果一級快取查找命中且資料狀態合法,則直接返回;
2、如果一級快取沒有命中,接下來Session會在當前NonExists記錄(相當於一個查詢黑名單,如果出現重複的無效查詢可以迅速做出判斷,從而提升效能)中進行查找,如果NonExists中存在同樣的查詢條件,則返回null;
3、如果一級快取查詢失敗查詢二級緩存,如果二級快取命中直接回傳;
4、如果先前的查詢都未命中,則發出SQL語句,如果查詢未發現對應記錄則將此查詢新增至Session的NonExists中加以記錄,並傳回null;
5、根據映射配置和SQL語句得到ResultSet,並建立對應的實體物件;
6、將物件納入Session(一級快取)的管理;
7、如果有對應的攔截器,則執行攔截器的onLoad方法;
8、如果開啟並設定了要使用二級緩存,則將資料物件納入二級快取;
9、回傳資料物件。
五、MyBatis中使用#和$來書寫佔位符有什麼區別?
#將傳入的資料都當成字串,會對傳入的資料自動加上引號;
$將傳入的資料直接顯示產生在SQL中。
注意:使用$佔位符可能會導致SQL注射攻擊,能用#的地方就不要使用$,寫order by子句的時候應該用$而不是#。
相關教學推薦:java面試題
#以上是java持久層面試題目(一)的詳細內容。更多資訊請關注PHP中文網其他相關文章!