Hibernate簡介
Hibernate是一個ORM( 對象關係映射 Object Relational Mapping)的框架,對JDBC進行了輕量級的對象封裝,讓開發人員更方便地操作數據庫。
Hibernate的優勢
1.Hibernate對JDBC訪問數據庫的代碼做了輕量級封裝,可以直接通過hibernate api ,保存對象到數據庫、且從數據庫中查詢到的就是對象!大大簡化了數據訪問層繁瑣的重複性代碼,並且減少了內存消耗,加快了運行效率。
2.Hibernate是一個基於JDBC的主流持久化框架,是一個優秀的ORM實現,它很大程度的簡化了dao(Data Access Object,數據訪問)層編碼工作。
3.Hibernate使用Java的反射機制,而不是字節碼增強程序類實現透明性。
4.Hibernate的性能非常好,映射的靈活性很出色。它支持很多關係型數據庫,從一對一到多對多的各種複雜關係。
5.可擴展性強,當本身功能不夠用時,可以自行編碼進行擴展。
Hibernate的環境配置
1.下載並引入有關 Hibernate的jar包。
2.創建數據庫及表。
3.寫entity(實體類) User。
4.寫實體類對應的映射文件 User.hbm.xml
5.寫核心配置文件hibernate.hbm.xml
6.Api操作數據庫
hibernate核心配置文件
<session-factory>
<!-- 數據庫連接信息配置 -->
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate01</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver
</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
數據庫方言配置:
作用: 告訴hibernate當前項目使用的數據庫; hibernate會根據方言配置的數據庫生成符合當前數據庫語法特徵的sql語句!
hibernate通過方言實現了跨數據庫平臺!
org.hibernate.dialect.MySQLDialect
mysql5或以下版本(不支持事務)
org.hibernate.dialect.MySQL5InnoDBDialect
mysql5.5以上版本
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
<!-- 顯示hibernate在運行時期底層生成的sql語句! -->
<property name="hibernate.show_sql">true</property>
<!-- 格式化sql語句 -->
<property name="hibernate.format_sql">true</property>
<!--
自動建表
update 如果表不存在則創建;表已經存在就不創建表,更新!
create 先刪除表,再創建表!
create-drop 在創建SessionFactory的時候創建表,在執行sf.close()方法時候刪除表!
validate 不創建表只做驗證:驗證映射文件與表是否一致,不一致報錯!(注意,如果對象中的屬性跟表中字段不一致則報錯,個數不用也會報錯,所以平時比較少用)
注意:
如果要用自動建表功能,必須加載映射文件!建表是根據映射文件創建的表!
-->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 加載映射文件(*.hbm.xml) -->
<mapping resource="cn/itcast/entity/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
映射文件配置User.hbm.xml
存放位置
持久化的實體類對象,與映射文件,放到同一個目錄!
<hibernate-mapping package="com.entity">
<!--
class 指定要映射的對象; table 指定對象對應的表
name 實體類對象名稱;
table 對象對應的表名稱;如果不寫默認與對象名稱一樣!
-->
<class name="User">
<!--
2. id 表示表的主鍵映射 ; hibernate要求表必須要有主鍵,那麼在映射中一定要配置主鍵!
主鍵生成策略:表示主鍵以何種方式生成!
class
identity mysql、sqlservlet等數據庫自增長方式
sequence oracle中以序列方式實現自增長!
native 自增長: 會根據底層數據庫支持的自增長方式自動選擇identity或者sequence其中一種!
assigned 手動指定主鍵值! (必須要自己控制唯一!)
uuid 系統生成唯一的uuid作爲主鍵
-->
<id name="id" column="tid">
<generator class="native"></generator>
</id>
<!-- 1. 非主鍵字段 -->
property
name javabean對象中的屬性名稱!
column 屬性對應的表中的字段名稱; 如果不指定,與屬性同名!
type 數據庫中字段的類型
方式1: 用hibernate提供的類型(大小寫要區分)
如: string、int、float、double、date
方式2: java中類型 (建議) (大小寫要區分)
如: java.lang.String 、java.util.Date
not-null="true" 字段非空; 默認是false,運行爲NULL
unique="false" 字段默認不添加唯一約束; 如果需要設置爲true
length="20" 字段字符最大長度爲20; 如果不指定,默認是255!
<property name="name" column="name" length="20" type="java.lang.String"></property>
<property name="salary" column="salary"></property>
<property name="birth" column="birth"></property>
</class>
</hibernate-mapping>
<!--聯合主鍵映射-->
<hibernate-mapping package="com.compositeId">
<class name="Person">
<!--
聯合主鍵對象映射
name="primary" 指定聯合主鍵對象
class=PersonPrimary 主鍵類型
key-property 聯合主鍵中每一個屬性、列名稱!
-->
<composite-id name="primary" class="PersonPrimary">
<key-property name="name" column="name" length="20"></key-property>
<key-property name="address" column="address" length="200"></key-property>
</composite-id>
<property name="age"></property>
<property name="remark" length="300"></property>
</class>
</hibernate-mapping>
Hibernate中持久化對象的狀態
- 瞬時狀態(Transient )
使用new操作符初始化的對象不是立刻就持久化的,他們的狀態是瞬時的。
(1) 不處於Session的緩存中。
(2) 在數據庫中沒有對應的記錄。
(3) 瞬時狀態的對象在內存中是孤立存在的,與數據庫中的數據無任何關聯,僅是一個信息攜帶的載體。不存在持久化標識OID(相當於主鍵值). - 持久化狀態(Persist)
(1) 位於一個session實例的緩存中,持久化對象總是被一個session實例關聯。
(2) 持久化對象和數據庫中的相關記錄對應。
(3) Session在清理緩存時,會根據持久化對象的屬性變化,來同步更新數據庫。
(4)持久態的對象存在持久化標識OID ,每條記錄只對應唯一的持久化對象,需要注意的是,持久態對象是在事務還未提交前變成持久態的。 - 遊離/脫管狀態(Detached )
(1)一般是指session關閉後對象的狀態, 爲脫管狀態(脫離session的管制)
(2) 脫管狀態的對象,在數據庫中有對應的記錄!
(3)脫管態對象存在持久化標識OID,並且仍然與數據庫中的數據存在關聯,只是失去了與當前Session的關聯,脫管狀態對象發生改變時Hibernate不能檢測到。
Hibernate一級緩存的特點
- 緩存的作用:減少對數據庫的訪問次數從而提高效率!,Session緩存是由hibernate自身去維護,通常用戶不能手動去自己維護Session緩存!
- 當應用程序調用Session接口的save()、update()、saveOrUpdate時,如果Session緩存中沒有相應的對象,Hibernate就會自動的把從數據庫中查詢到的相應對象信息加入到一級緩存中去。
- 當調用Session接口的load()、get()方法,以及Query接口的list()、iterator()方法時,會判斷緩存中是否存在該對象,有則返回,不查詢數據庫,如果緩存中沒有要查詢對象,再去數據庫中查詢對應對象。
- 當調用Session的close()方法時,Session緩存會被清空。
- Session 能夠在某些時間點,按照緩存中對象的變化,執行相關的 SQL 語句來同步更新數據庫,這一過程被稱爲刷出緩存(flush)。
數據庫中多表之間的三種關聯關係
- 一對多:在多的一方添加一的一方的主鍵作爲外鍵。
- 多對多:產生中間關係表,引入兩個實體的主鍵作爲外鍵,兩個主鍵成爲聯合主鍵。
- 一對一:在任意一方引入對方主鍵作爲外鍵(開發中使用非常少)。
Cascade級聯操作
級聯操作是指控制權沒有反轉,當主控方執行保存、更新或者刪除操作時,其關聯對象(被控方)也執行相同的操作。在映射文件中通過對cascade屬性的設置來控制是否對關聯對象採用級聯操作。
cascade定義的是有關聯關係的對象之間的級聯關係,cascade的相關屬性可選值如下:
1. all :所有情況下均進行關聯操作。
2. none:所有情況下均不進行關聯操作。這是默認值。
3. save-update:在執行save、update或saveOrUpdate時進行關聯操作。
4. delete:在執行delete時進行關聯操作。
5. save-update,delete :在執行save、update或delete時進行關聯操作。
Hibernate的檢索方式
Hibernate的檢索方式主要有5種,分別爲導航對象圖檢索方式、OID檢索方式、HQL檢索方式、QBC檢索方式和SQL檢索方式。