一、經典的原因
Hibernate是一個對象關係映射的框架,顧名思義就是把java的實體映射到數據庫,並且自動幫助我們生成sql語句,這樣我們就可以使用對象隨心所欲的使用對象編程操作數據庫,可以說是風靡一時,但是這也成爲Hibernate框架的一個詬病,因爲sql語句我們無法直接操作,對sql的優化造成了困擾,我想這也是MyBatis興起的一個重要原因吧,兩者的不同和優缺點這裏暫時不做詳細對比了
二、基礎核心
1.Configuration
通過Configuration讀取數據庫配置文件,並創建好與數據庫的鏈接,當使用anntation方式時,使用AnnotationConfiguration;
2.SessionFactory
session創建的工廠,維護着數據庫的連接池,創建session有兩種方式
openSession:每次都創建新的session,使用完手動close
getCurrentSession:拿到當前的session,在commit後自動關閉
上述兩種創建方式完全不同,不要混合使用具體細節不在贅述
3.Session
接口有着不同的實現,管理一個數據庫連接,執行增刪改查
4.對象三種狀態
hibernate中對象的狀態跟主鍵id有沒有存在及位置有關
①沒有id:transient
②數據庫中有沒有id: persistent 內存中有,緩存中有,數據庫中有
③緩存中有沒有id: detached 內存中有,緩存沒有,數據庫有
緩存指的是session管理的內存
persistent和detached區別在於session時候關閉,如未關閉則處於persistent
關閉則緩存釋放,處於detached狀態
5.id生成的策略
@GeneratorValue指定我們的id是哪個
strategy:指定具體的id值在生成時候的策略
①GenerationType.IDENTITY 爲自增長
②GenerationType.SEQUENCE 支持sequence機制的數據庫(mysql不支持),如oracle
③GenerationType.TABLE 使用第三方表生成,根據表名,記錄每張表中id的最大值,可指定步長
④GenerationType.AUTO 根據數據庫不同,按照不同數據庫默認的方式生成
6.常用增刪改查
delete:對象必須處於,persistent或detached狀態,即有id
get:返回我們需要的對象,直接返回
load:返回我們需要的對象,返回的對象其實是一個代理,真正的sql語句是在對象中拿值的時候執行的,如果在session關閉後取對象中的值會有proxy找不到的錯誤,因爲session已經關閉;解決方案:在攔截器中控制請求結束後關閉session
update:更新數據,默認會把所有的字段都做一遍檢查更新
優化處理:
①屏蔽無關內容的更新,在不需要做更新的字段指定updateAble=false
②merge合併,會先load一遍,比較不同之後再做update
③HQL,面向對象的sql語句,很是強大
clear():清除session緩存
flush():強制和數據庫進行數據同步,在commit方法內部都有flush的執行
三、關係映射
因爲hibernate的思想就是把對象映射到數據庫關係中,所以對象之間的關係與數據庫對應,並且有單向和雙向的區別;方向在與是否能通過一方查找到另一方
①一對一
外鍵:數據庫表中的表現,作爲另一張表的外鍵
單向:@OneToOne,需要有外鍵的一方指定即可
雙向:雙方都要指定@OneToOne,一般還需設置一個主導方 通過mappedBy指定,再設置@JoinColumn字段名單向和雙向在數據庫中的表現都是一樣的,一張表中存在外鍵
主鍵:不設置外鍵,不能保證數據庫唯一
@PrimaryKeyJonColumn 不會產生外鍵,只是在形式上做了一種約束,數據庫表沒變化
②一對多
單向一對多:@OneToManay,默認會當做多對多來處理,生成第三張表
使用@JoinColumn,這時少的一方主鍵作爲多的一方外鍵來處理
單向多對一:@ManayToOne,直接在多的一方設置即可
雙向:分別制定@OneToManay 和 @ManayToOne
一定要配置mappedBy,如果考慮的是多的一方,那麼在少的一方配置,反之亦然
③多對多:用聯合主鍵作爲第三張表
@ManayToManay
@JoinTable指定第三張表的表名和內容
@JoinTable(name=”“,
joinColumns={@JoinColumn(name=”“)},
inverseJoinColumns={@JoinColumn(name=”“)}
)
joinColumns指定的是當前對象在第三張表中設置,inverseJoinColumns是另外一個類在第三張表中的設置
兩者都用的數組,是因爲考慮到兩個對象本身用的就是聯合主鍵,那麼在指定第三張表的時候每個對象可能需要指定多個名字
四、總結
1.hibernate對於對象映射到數據庫的配置是真的繁瑣,一旦表非常多,應該不是一個很好的選擇
2.對於用不用無關字段作爲主鍵這個事情還有待商榷,感覺主鍵最好用表中的數據
3.估計剛使用hibernate會很懵逼的,對於dao層封裝的這麼“完整”,完全看不到sql