Java面試題——Hibernate

目錄

 

爲什麼要使用 hibernate?

什麼是 ORM 框架?

hibernate 中如何在控制檯查看打印的 sql 語句?

hibernate 有幾種查詢方式?

hibernate 實體類可以被定義爲 final 嗎?

在 hibernate 中使用 Integer 和 int 做映射有什麼區別?

hibernate 是如何工作的?

get()和 load()的區別?

說一下 hibernate 的緩存機制?

hibernate 對象有哪些狀態?

在 hibernate 中 getCurrentSession 和 openSession 的區別是什麼?

hibernate 實體類必須要有無參構造函數嗎?爲什麼?


爲什麼要使用 hibernate?

什麼是 ORM 框架?

ORM:Object Relational Mapping(對象關係映射)。

指的是將一個Java中的對象與關係型數據庫中的表建立一種映射關係,從而操作對象就可以操作數據庫中的表

hibernate 中如何在控制檯查看打印的 sql 語句?

<!-- 打印SQL -->
<property name="hibernate.show_sql">true</property>

hibernate 有幾種查詢方式?

三種查詢方式

  • HQL查詢:Hibernate Query Language,Hibernate的查詢語言,是一種面向對象的方式的查詢語言,語法類似SQL。通過session.createQuery(),用於接收一個HQL進行查詢方式。
  • QBC查詢:Query By Criteria,條件查詢。是一種更加面向對象化的查詢的方式。QBC查詢:Query By Criteria,條件查詢。是一種更加面向對象化的查詢的方式。
  • SQL查詢:通過使用sql語句進行查詢

hibernate 實體類可以被定義爲 final 嗎?

可以將Hibernate的實體類定義爲final類,但這種做法並不好。因爲Hibernate會使用代理模式在延遲關聯的情
況下提高性能,如果你把實體類定義成final類之後,因爲 Java不允許對final類進行擴展,所以Hibernate就
無法再使用代理了,如此一來就限制了使用可以提升性能的手段。不過,如果你的持久化類實現了一個接口而且在
該接口中聲明瞭所有定義於實體類中的所有public的方法輪到話,你就能夠避免出現前面所說的不利後果

在 hibernate 中使用 Integer 和 int 做映射有什麼區別?

返回數據庫字段值是null的話,int類型會報錯。int是基本數據類型,其聲明的是變量,而null則是對象。所以
hibernate實體建議用integer;
通過jdbc將實體存儲到數據庫的操作通過sql語句,基本數據類型可以直接存儲,對象需要序列化存儲。
使用包裝類型可以在pojo類中使用驗證註解對屬性的值做校驗

hibernate 是如何工作的?

1、調用Configuration類,通過Configuration config = new Configuration().configure();讀取並
解析hibernate.cfg.xml配置文件 
2、通過hibernate.cfg.xml中的<mapping resource="com/xxx/Xxx.hbm.xml"/>讀取並解析映射信息 
3、通過SessionFactory sessionfactory = config.buildSessionFactory();通過讀取的這些配置信息
創建一個sessionfactory對象 
4、Session session = sessionfactory.openSession();通過sessionfactory生成一個Sesssion對象 
5、Transaction ts = session.beginTransaction();通過session對象創建並啓動事務Transation 
6、通過Session對象的get()、sava()、update()、delete()和saveOrupdate()等方法對PO進行加載,保
存,更新,刪除等操作; 
7、在查詢的情況下,可通過Session對象生成一個Query對象,然後利用Query對象執行查詢操作。如果沒有異
常,Transaction對象將提交這些操作結果到數據庫中,否則會回滾事務。 

get()和 load()的區別?

1. 對於Hibernate get方法,Hibernate會確認一下該id對應的數據是否存在,首先在session緩存中查找,
然後在二級緩存中查找,還沒有就查詢數據庫,數據 庫中沒有就返回null。這個相對比較簡單,也沒有太大的爭
議。主要要說明的一點就是在這個版本(bibernate3.2以上)中get方法也會查找二級緩存!


2. Hibernate load方法加載實體對象的時候,根據映射文件上類級別的lazy屬性的配置(默認爲true),分情況討論: 

(1)若爲true,則首先在Session緩存中查找,看看該id對應的對象是否存在,不存在則使用延遲加載,返回實體
的代理類對象(該代理類爲實體類的子類,由CGLIB動態生成)。等到具體使用該對象(除獲取OID以外)的時候,再
查詢二級緩存和數據庫,若仍沒發現符合條件的記錄,則會拋出一個ObjectNotFoundException。

(2)若爲false,就跟Hibernateget方法查找順序一樣,只是最終若沒發現符合條件的記錄,則會拋出一個ObjectNotFoundException。


get方法
		 採用的是立即加載,執行到這行代碼的時候,就會馬上發送SQL語句去查詢。
		 查詢後返回是真實對象本身。
		 查詢一個找不到的對象的時候,返回null
		 
		 load方法
		 採用的是延遲加載(lazy懶加載),執行到這行代碼的時候,不會發送SQL語句,當真正使用這個對象
的時候纔會發送SQL語句。
		 查詢後返回的是代理對象。javassist-3.18.1-GA.jar 利用javassist技術產生的代理。
		 查詢一個找不到的對象的時候,返回ObjectNotFoundException



說一下 hibernate 的緩存機制?

Hibernate緩存的作用:
    Hibernate是一個持久層框架,經常訪問物理數據庫,爲了降低應用程序對物理數據源訪問的頻次,從而
提高應用程序的運行性能。緩存內的數據是對物理數據源中的數據的複製,應用程序在運行時從緩存讀寫數
據,在特定的時刻或事件會同步緩存和物理數據源的數據
Hibernate緩存分類:
  Hibernate緩存包括兩大類:Hibernate一級緩存和Hibernate二級緩存
Hibernate一級緩存又稱爲“Session的緩存”,它是內置的,意思就是說,只要你使用hibernate就必須使用
session緩存。由於Session對象的生命週期通常對應一個數據庫事務或者一個應用事務,因此它的緩存是事
務範圍的緩存。在第一級緩存中,持久化類的每個實例都具有唯一的OID。 
Hibernate二級緩存又稱爲“SessionFactory的緩存”,由於SessionFactory對象的生命週期和應用程序的
整個過程對應,因此Hibernate二級緩存是進程範圍或者集羣範圍的緩存,有可能出現併發問題,因此需要採
用適當的併發訪問策略,該策略爲被緩存的數據提供了事務隔離級別。第二級緩存是可選的,是一個可配置的
插件,在默認情況下,SessionFactory不會啓用這個插件。

什麼樣的數據適合存放到第二級緩存中?   
1 很少被修改的數據   
2 不是很重要的數據,允許出現偶爾併發的數據   
3 不會被併發訪問的數據   
4 常量數據   
不適合存放到第二級緩存的數據?   
1經常被修改的數據   
2 .絕對不允許出現併發訪問的數據,如財務數據,絕對不允許出現併發   
3 與其他應用共享的數據。 

Hibernate查找對象如何應用緩存?
當Hibernate根據ID訪問數據對象的時候,首先從Session一級緩存中查;查不到,如果配置了二級緩存,那
麼從二級緩存中查;如果都查不到,再查詢數據庫,把結果按照ID放入到緩存
刪除、更新、增加數據的時候,同時更新緩存

Hibernate管理緩存實例
無論何時,我們在管理Hibernate緩存(Managing the caches)時,當你給save()、update()或
saveOrUpdate()方法傳遞一個對象時,或使用load()、 get()、list()、iterate() 或scroll()方法獲
得一個對象時, 該對象都將被加入到Session的內部緩存中。 
當隨後flush()方法被調用時,對象的狀態會和數據庫取得同步。 如果你不希望此同步操作發生,或者你正處
理大量對象、需要對有效管理內存時,你可以調用evict() 方法,從一級緩存中去掉這些對象及其集合。

hibernate 對象有哪些狀態?

在 hibernate 中 getCurrentSession 和 openSession 的區別是什麼?

1.openSession 從字面上可以看得出來,是打開一個新的session對象,而且每次使用都是打開一個新的
session,假如連續使用多次,則獲得的session不是同一個對象,並且使用完需要調用close方法關閉session。

2. getCurrentSession ,從字面上可以看得出來,是獲取當前上下文一個session對象,當第一次使用此方法
時,會自動產生一個session對象,並且連續使用多次時,得到的session都是同一個對象,這就是與
openSession的區別之一,簡單而言,getCurrentSession 就是:如果有已經使用的,用舊的,如果沒有,建新的。

注意:在實際開發中,往往使用getCurrentSession多,因爲一般是處理同一個事務(即是使用一個數據庫的情
況),所以在一般情況下比較少使用openSession或者說openSession是比較老舊的一套接口了;

hibernate 實體類必須要有無參構造函數嗎?爲什麼?

因爲hibernate框架會調用這個默認構造方法來構造實例對象。

 

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