hibernate讀書筆記

1. Hibernate建立過程

l  引入jar java

l  加入配置文件hibernate.cfg.xml mysql

l  建立數據 算法

l  建立實體,配置映射:1xml2jpa(推薦)   sql

l  測試:1、加載配置文件;2、建立SessionFactory3openSession4beginTransaction5save6commit7close 數據庫

2. HelloWorld

Xml配置方式:實體對應hbm.xml api

Annotation配置方式:類名用@Entity註解 緩存

3. Hibernate模擬實現

l  建立數據庫 性能優化

l  與表創建映射關係 服務器

l  提供保存對象方法 session

l  將對象轉換爲sql語句

l  執行sql

l  關閉連接

4. 常見OR框架

jFinal

MyBatis

5. hbm2ddl

create:每次啓動都會刪除表後重建。數據會丟失

update:根據最新實體對數據表進行同步修改。強烈推薦。

6. 先建表仍是先建類

best practise:先建表,方便對數據庫進行優化

7. 搭建Logback日誌環境

l  引入slf4j-api.jar,代碼以slf4j-api爲標準開發,方便切換日誌實現

l  引入logback-core.jarlogback-classiclogback-accesslogback-classic實現了slf4j-api,不用再引入轉換包

l  配置logback.xml日誌等級、格式

8. 搭建Junit日誌環境

@Test:執行的測試單元

@BeforeClass:執行測試單元前執行,定義爲static

@AfterClass:執行測試單元后執行,定義爲static

l  測試驅動開發(Test-Driven Development):不可運行/可運行/重構

9. BaseConfig

showsql:顯示hibernate執行的sql語句

formatsql:將sql語句格式化後輸出

10.    Annotation字段映射

Xml:某屬性不須要映射,則不配置對應屬性

Annotation:某屬性不須要映射,則配置@Transient@Transient只有放在get方法上纔有效(測試的4.3.5版本)。

l  強烈推薦使用Annotation方式,配置簡便。

l  默認配置@Basic註解

Enum類型屬性:使用@Enumerated註解:value可選EnumType.STRINGEnumType.ORDINAL,數據庫根據類型建立對應類型

Date類型:使用@Temporal註解:value可選TemporalType.DATETemporalType.TIMETemporalType.TIMESTAMP,數據庫根據類型建立對應類型

Best practise:註解放在get方法上面,由於放在屬性上面暴露的是private的屬性,那樣就破壞了面向對象的封裝性

11.    ID的生成策略

Xml:經常使用native、uuid、identitysequencenative會根據數據庫自動映射,mysql下爲identity(auto_increment)oracle下爲sequence

Annotationjpa只支持4種:GenerationType.AUTO、GenerationType.IDENTITYGenerationType.SEQUENCEGenerationType.TABLE,默認GenerationType.AUTO,相似xmlnative

Sequence:默認只生成一個名爲hibernate_seq的序列,全部的表共用一個序列。也可使用@GeneratedValue(strategy = GenerationType.SEQUENCE, generator="teacherSEQ")指定序列,而且能夠在class上面用@SequenceGenerator(name = "teacherSEQ", sequenceName = "teacher_SEQ")指定序列別名

TableGenerator:使用場景,真正提供跨數據庫平臺id的生成策略(使用AUTO沒法完美解決跨平臺,例:Oracle數據庫與Mysql數據庫id的生成策略不一致,Oracle使用AUTO只能生成一個sequence,沒法每一個表自增)。使用較少,瞭解便可。

l  複合/聯合主鍵:xml中使用composite-id指定;annotation有三種方式實現,從23選擇一種便可:

1.     @Id @Embeddable

2.     @EmbeddedId

3.     @Id @IdClass

12.    SessionFactory

l  由hibernate.cfg.xml配置文件決定生成規則

configure()可加載指定配置文件

l  一般狀況每一個應用只須要一個SessionFactory。訪問多個數據庫時每一個數據庫對應一個。

getCurrentSessionopenSession都可得到session,區別以下:

1.     openSession每次打開一個新鏈接,提交後手動close

2.     getCurrentSession根據配置(current_session_context_class)策略從上下文獲取已經打開的session,若是沒有則新增一個,不須要手動關閉session

3.     getCurrentSession主要用於界定事務邊界

4.     兩種方式生成的session不能混用,即openSession打開了一個連接,則getCurrentSession沒法獲取到該連接

current_session_context_class可配置爲:JTAthread

1.     thread依賴與connection事務

2.     JTAjava transaction api,用於多個數據庫分佈式事務

13.    Session的核心API

save,保存對象操做,對象有三種狀態:

1.     transient:內存有、緩存沒有、數據庫沒有——ID沒有

2.     persistent:內存有、緩存有、數據庫有——ID

3.     detached:內存有、緩存沒有、數據庫有——ID

delete,只要對象的id有值,就能刪除

loadget:獲取數據對象,差異:

1.     load返回的是代理對象,延遲加載,在具體使用對象內容時才推送sql語句。(測試中發現:超時也會執行,具體超時時間不定)

2.     get即時加載,不會延遲

3.     數據不存在:load報錯;get不報錯,返回null

Update

1.     用來更新detached對象,更新後轉爲persistent狀態

2.     更新transient對象會報錯

3.     能夠更新本身設定idtransient對象(前提《==數據庫有對應記錄)

4.     persistent狀態的對象只要設定值就會發生更新(特別注意:不須要save就會執行更新)

5.     更新部分更改的字段

1.     對於單個屬性:xml設定propertyupdate屬性,annotation採用@Column(updatable = false)註解實現,這種狀況不多用,不靈活

2.     整個對象:xml使用dynamic-update="true"實現,JPA無對應實現。hibernate擴展annotation註解@DynamicUpdate(true)能夠實現。同一個session能夠,跨session不行,不過能夠用merge實現。

3.     使用HQLEJBQL)(推薦使用)

saveOrUpdate:不存在idsave,存在idupdate

clear

1.     不管是get仍是load,都會首先查找緩存(一級緩存),若是沒有,纔會去數據庫查找

2.     調用clear方法能夠強制清除session緩存

Flush

1.     強制緩存與數據庫同步(強制推送sql語句)

2.     Flushmode,知道便可,不重要

find:已通過時

SchemaExport:主要用來顯示sql腳本,方便保留數據庫腳本信息

14.    表間關係映射

l  一對一單向外鍵關聯

1.     Annotation@OneToOne實現,@JoinColumn指定外鍵名稱

2.     Xml:採用many-to-one標籤指定,設置unique="true"表示惟一

l  一對一雙向外鍵關聯

1.     Annotation@OneToOnemappedBy。強烈推薦

2.     Xml<many-to-one unique<one-to-one property-ref,很差理解

3.     實際應用中,採用雙向關聯,都會使用mappedBy減小外鍵個數

4.     單向、雙向生成的數據庫都同樣,可是雙向模式在任一對象上面都能拿到關聯的數據對象

l  一對一單向主鍵關聯(不重要)

l  一對一雙向主鍵關聯(不重要)

l  聯合主鍵

1.     @JoinColumns來關聯

l  組件映射

1.     使用@Embedded指定嵌入的組件

2.     組件中的屬性不能重複,可採用更名或者指定@Column(name = 指定列表

l  多對一單向:在多方向增長@ManyToOne

l  一對多單向:在少方加@OneToMany @JoinColumn指定關聯外鍵

l  一對多、多對一雙向關聯:

1.     Annotation:沒法指定列名?

2.     Xmlonekey必須與manycolumn一致,不然生成多個外鍵

l  多對多單向關聯:

@ManyToMany

   @JoinTable(name = "t_s", // 關聯中間表名

      joinColumns = @JoinColumn(name = "teacher_id", referencedColumnName = "id"),  // 中間表,關聯當前表(teacher)的字段信息

      inverseJoinColumns = @JoinColumn(name = "student_id", referencedColumnName = "id") // 中間表,關聯引用的字段(student)信息

l  多對多雙向關聯:極少用

15.    表關聯操做

l  一對多關聯操做:

1.     CUD操做經過cascade = CascadeType.ALL實現級聯

1.     設置在哪一個對象,就對操做的那個對象有做用

2.     技巧:儘可能操做關係爲多(many)的表,操做方便

2.     R(Retrieve)操做經過fetch = FetchType.EAGER控制加載規則

1.     OneToMany對象默認是FetchType.LAZY,即不關聯加載many數據

2.     ManyToOne對象默認是FetchType. EAGER,即關聯加載one數據

3.     best practiceOneToMany只在many數據量不多的狀況下設置爲EAGER

l  多對多關聯操做:

1.     保存設置@JoinTable註解的對象才能保存成功,最佳實踐——進行雙向設置

l  集合映射:

1.     Set:無順序

2.     List:有順序,經過@OrderBy("name ASC")指定排序規則

3.     Map:經過@MapKey(name = "id")指定mapkey

l  集成映射:

1.     Single_Table:數據存儲在一張表,缺點:存儲數據冗餘。適用於字段少,總數據較少的狀況;

2.     Table_Per_Class

1.     每一個類映射爲一張表

2.     爲保證惟一性(多態讀取數據),需利用@TableGenerator生成主鍵

3.     缺點:查詢須要將全部的表union。適用於字段多,多態(父類)查詢少的狀況

3.     JOINED

1.     每一個類映射爲一張表,子類不包含父類除id外的字段

2.     缺點:查詢父類會關聯全部表,查詢子類都會關聯父類表。

16.    Hibernate查詢語言

HQL vs EJBQL

1.     NativeSQL > HQL > EJBQL(JP QL 1.0) > QBC(Query By Critira)

2.     總結:QL應該和導航關係結合,共同爲查詢提供服務

17.    性能優化

l  注意session.clear()的運用,尤爲在不斷分頁的循環的時候

1.     遍歷大集合

2.     另一種形式的內存泄露

18.    1+N問題

ManyToOne對象默認是FetchType. EAGER,即關聯加載one數據。當只取many的數據時,會將每條數據關聯的one經過一條sql語句取出來,形成數據庫的負擔。解決的方案有:

1.     fetch設置爲FetchType.LAZY,在合適的時候加載數據

2.     Entity上面加@BatchSize屬性,設置size,減小執行取數據次數

3.     利用QBC語句進行查詢,或者直接採用HQL加上join fetch條件查詢關聯數據

19.    listiterator

l  相同點:獲取數據集。

l  不一樣點:

1.     list一次性取出全部數據;iterator先取出id,在訪問其餘屬性的時再利用ID取數據,相似延遲加載。

2.     同一個session中,list方式每次都會從數據庫獲取數據;iterator能利用session緩存,若是session中存在,則直接從session中返回。

20.    一級緩存、二級緩存和查詢緩存

l  什麼是緩存:緩存就是將數據庫常常用到的數據存儲到服務器內存或磁盤上面,提供快速查詢能力的技術。

l  一級緩存,session緩存,存儲在內存中。eg:同一個session裏面,屢次load同一個對象。

l  二級緩存,sessionFactory緩存。對全部session緩存統一進行緩存,故在多個session裏面,load同一個對象,不用查詢數據庫。適合作二級緩存的特色:

1.     查詢頻率高

2.     數據改動小

3.     數據量不大

l  打開二級緩存:

1.     hibernate.cfg.xml文件

<property name="cache.use_second_level_cache">true</property>

<property name="hibernate.cache.region.factory_class">org.hibernate.cache.EhCacheRegionFactory</property>

2.     制定須要緩存的數據實體。

1.     須要緩存的domain加註解

@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)

2.     Best practic:在hibernate.cfg.xml中增長

<class-cache class="com.bjsxt.hibernate.Category" usage="read-write"/>

load默認使用二級緩存,iterator默認使用二級緩存。

list默認往二級緩存加載,但查詢的時候不使用,查詢每次都到數據庫執行。

l  查詢緩存:用來緩存相同查詢語句的結果集

1.     hibernate.cfg.xml文件

<property name="cache.use_query_cache">true</property>

2.     調用Query設置setCacheable(true)方法指明使用二級緩存

l  緩存算法:當緩存的容量滿時

1.     LRULFUFIFO

1.     Least Recently Used:最近不多用

2.     Least Frequently Used:命中率較低

3.     First In First Out:先進先出

2.     memoryStoreEvictionPolicy=」LRU」(ehcache)

21.    事務隔離機制

l  事務的特徵:ACID

l  事務併發可能出現的問題:

l  數據庫的事務隔離機制

 

相關文章
相關標籤/搜索