致敬經典之Hibernate

一、經典的原因

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