l 引入jar包 java
l 加入配置文件hibernate.cfg.xml mysql
l 建立數據 算法
l 建立實體,配置映射:1、xml;2、jpa(推薦) sql
l 測試:1、加載配置文件;2、建立SessionFactory;3、openSession;4、beginTransaction;5、save;6、commit;7、close 數據庫
l Xml配置方式:實體對應hbm.xml api
l Annotation配置方式:類名用@Entity註解 緩存
l 建立數據庫 性能優化
l 與表創建映射關係 服務器
l 提供保存對象方法 session
l 將對象轉換爲sql語句
l 執行sql
l 關閉連接
l jFinal
l MyBatis
l create:每次啓動都會刪除表後重建。數據會丟失
l update:根據最新實體對數據表進行同步修改。強烈推薦。
l best practise:先建表,方便對數據庫進行優化
l 引入slf4j-api.jar,代碼以slf4j-api爲標準開發,方便切換日誌實現
l 引入logback-core.jar、logback-classic、logback-access。logback-classic實現了slf4j-api,不用再引入轉換包
l 配置logback.xml日誌等級、格式
l @Test:執行的測試單元
l @BeforeClass:執行測試單元前執行,定義爲static
l @AfterClass:執行測試單元后執行,定義爲static
l 測試驅動開發(Test-Driven Development):不可運行/可運行/重構
l showsql:顯示hibernate執行的sql語句
l formatsql:將sql語句格式化後輸出
l Xml:某屬性不須要映射,則不配置對應屬性
l Annotation:某屬性不須要映射,則配置@Transient,@Transient只有放在get方法上纔有效(測試的4.3.5版本)。
l 強烈推薦使用Annotation方式,配置簡便。
l 默認配置@Basic註解
l Enum類型屬性:使用@Enumerated註解:value可選EnumType.STRING、EnumType.ORDINAL,數據庫根據類型建立對應類型
l Date類型:使用@Temporal註解:value可選TemporalType.DATE、TemporalType.TIME、TemporalType.TIMESTAMP,數據庫根據類型建立對應類型
l Best practise:註解放在get方法上面,由於放在屬性上面暴露的是private的屬性,那樣就破壞了面向對象的封裝性
l Xml:經常使用native、uuid、identity、sequence:native會根據數據庫自動映射,mysql下爲identity(auto_increment);oracle下爲sequence
l Annotation:jpa只支持4種:GenerationType.AUTO、GenerationType.IDENTITY、GenerationType.SEQUENCE、GenerationType.TABLE,默認GenerationType.AUTO,相似xml中native
l Sequence:默認只生成一個名爲hibernate_seq的序列,全部的表共用一個序列。也可使用@GeneratedValue(strategy = GenerationType.SEQUENCE, generator="teacherSEQ")指定序列,而且能夠在class上面用@SequenceGenerator(name = "teacherSEQ", sequenceName = "teacher_SEQ")指定序列別名
l TableGenerator:使用場景,真正提供跨數據庫平臺id的生成策略(使用AUTO沒法完美解決跨平臺,例:Oracle數據庫與Mysql數據庫id的生成策略不一致,Oracle使用AUTO只能生成一個sequence,沒法每一個表自增)。使用較少,瞭解便可。
l 複合/聯合主鍵:xml中使用composite-id指定;annotation有三種方式實現,從2、3選擇一種便可:
1. @Id @Embeddable
2. @EmbeddedId
3. @Id @IdClass
l 由hibernate.cfg.xml配置文件決定生成規則
l configure()可加載指定配置文件
l 一般狀況每一個應用只須要一個SessionFactory。訪問多個數據庫時每一個數據庫對應一個。
l getCurrentSession、openSession都可得到session,區別以下:
1. openSession每次打開一個新鏈接,提交後手動close
2. getCurrentSession根據配置(current_session_context_class)策略從上下文獲取已經打開的session,若是沒有則新增一個,不須要手動關閉session
3. getCurrentSession主要用於界定事務邊界
4. 兩種方式生成的session不能混用,即openSession打開了一個連接,則getCurrentSession沒法獲取到該連接
l current_session_context_class可配置爲:JTA、thread
1. thread依賴與connection事務
2. JTA:java transaction api,用於多個數據庫分佈式事務
l save,保存對象操做,對象有三種狀態:
1. transient:內存有、緩存沒有、數據庫沒有——ID沒有
2. persistent:內存有、緩存有、數據庫有——ID有
3. detached:內存有、緩存沒有、數據庫有——ID有
l delete,只要對象的id有值,就能刪除
l load、get:獲取數據對象,差異:
1. load返回的是代理對象,延遲加載,在具體使用對象內容時才推送sql語句。(測試中發現:超時也會執行,具體超時時間不定)
2. get即時加載,不會延遲
3. 數據不存在:load報錯;get不報錯,返回null
l Update
1. 用來更新detached對象,更新後轉爲persistent狀態
2. 更新transient對象會報錯
3. 能夠更新本身設定id的transient對象(前提《==數據庫有對應記錄)
4. persistent狀態的對象只要設定值就會發生更新(特別注意:不須要save就會執行更新)
5. 更新部分更改的字段
1. 對於單個屬性:xml設定property的update屬性,annotation採用@Column(updatable = false)註解實現,這種狀況不多用,不靈活
2. 整個對象:xml使用dynamic-update="true"實現,JPA無對應實現。hibernate擴展annotation註解@DynamicUpdate(true)能夠實現。同一個session能夠,跨session不行,不過能夠用merge實現。
3. 使用HQL(EJBQL)(推薦使用)
l saveOrUpdate:不存在id時save,存在id時update
l clear:
1. 不管是get仍是load,都會首先查找緩存(一級緩存),若是沒有,纔會去數據庫查找
2. 調用clear方法能夠強制清除session緩存
l Flush
1. 強制緩存與數據庫同步(強制推送sql語句)
2. Flushmode,知道便可,不重要
l find:已通過時
l SchemaExport:主要用來顯示sql腳本,方便保留數據庫腳本信息
l 一對一單向外鍵關聯
1. Annotation:@OneToOne實現,@JoinColumn指定外鍵名稱
2. Xml:採用many-to-one標籤指定,設置unique="true"表示惟一
l 一對一雙向外鍵關聯
1. Annotation:@OneToOne,mappedBy。強烈推薦
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. Xml:one的key必須與many的column一致,不然生成多個外鍵
l 多對多單向關聯:
@ManyToMany
@JoinTable(name = "t_s", // 關聯中間表名
joinColumns = @JoinColumn(name = "teacher_id", referencedColumnName = "id"), // 中間表,關聯當前表(teacher)的字段信息
inverseJoinColumns = @JoinColumn(name = "student_id", referencedColumnName = "id") // 中間表,關聯引用的字段(student)信息
l 多對多雙向關聯:極少用
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 practice:OneToMany只在many數據量不多的狀況下設置爲EAGER。
l 多對多關聯操做:
1. 保存設置@JoinTable註解的對象才能保存成功,最佳實踐——進行雙向設置
l 集合映射:
1. Set:無順序
2. List:有順序,經過@OrderBy("name ASC")指定排序規則
3. Map:經過@MapKey(name = "id")指定map的key
l 集成映射:
1. Single_Table:數據存儲在一張表,缺點:存儲數據冗餘。適用於字段少,總數據較少的狀況;
2. Table_Per_Class:
1. 每一個類映射爲一張表
2. 爲保證惟一性(多態讀取數據),需利用@TableGenerator生成主鍵
3. 缺點:查詢須要將全部的表union。適用於字段多,多態(父類)查詢少的狀況
3. JOINED:
1. 每一個類映射爲一張表,子類不包含父類除id外的字段
2. 缺點:查詢父類會關聯全部表,查詢子類都會關聯父類表。
l HQL vs EJBQL
1. NativeSQL > HQL > EJBQL(JP QL 1.0) > QBC(Query By Critira)
2. 總結:QL應該和導航關係結合,共同爲查詢提供服務
l 注意session.clear()的運用,尤爲在不斷分頁的循環的時候
1. 遍歷大集合
2. 另一種形式的內存泄露
l ManyToOne對象默認是FetchType. EAGER,即關聯加載one數據。當只取many的數據時,會將每條數據關聯的one經過一條sql語句取出來,形成數據庫的負擔。解決的方案有:
1. 將fetch設置爲FetchType.LAZY,在合適的時候加載數據
2. 在Entity上面加@BatchSize屬性,設置size,減小執行取數據次數
3. 利用QBC語句進行查詢,或者直接採用HQL加上join fetch條件查詢關聯數據
l 相同點:獲取數據集。
l 不一樣點:
1. list一次性取出全部數據;iterator先取出id,在訪問其餘屬性的時再利用ID取數據,相似延遲加載。
2. 同一個session中,list方式每次都會從數據庫獲取數據;iterator能利用session緩存,若是session中存在,則直接從session中返回。
l 什麼是緩存:緩存就是將數據庫常常用到的數據存儲到服務器內存或磁盤上面,提供快速查詢能力的技術。
l 一級緩存,session緩存,存儲在內存中。eg:同一個session裏面,屢次load同一個對象。
l 二級緩存,sessionFactory緩存。對全部session緩存統一進行緩存,故在多個session裏面,load同一個對象,不用查詢數據庫。適合作二級緩存的特色:
1. 查詢頻率高
2. 數據改動小
3. 數據量不大
l 打開二級緩存:
<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"/>
l load默認使用二級緩存,iterator默認使用二級緩存。
l list默認往二級緩存加載,但查詢的時候不使用,查詢每次都到數據庫執行。
l 查詢緩存:用來緩存相同查詢語句的結果集
1. hibernate.cfg.xml文件
<property name="cache.use_query_cache">true</property>
2. 調用Query設置setCacheable(true)方法指明使用二級緩存
l 緩存算法:當緩存的容量滿時
1. LRU、LFU、FIFO
1. Least Recently Used:最近不多用
2. Least Frequently Used:命中率較低
3. First In First Out:先進先出
2. memoryStoreEvictionPolicy=」LRU」(ehcache)
l 事務的特徵:ACID
l 事務併發可能出現的問題:
l 數據庫的事務隔離機制