一、對象關係映射文件
-
POJO類和關係數據庫之間的映射可以用一個XML文檔來定義
-
在運行時Hibernate將根據這個映射文件來生成各種SQL語句
-
映射文件的拓展名爲 .hbm.xml
1.映射文件說明
<hibernate-mapping>
<class name="com.yfy.hibernate.entity.NewsEntity" table="news" schema="hibernate" dynamic-insert="true" dynamic-update="true" >
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="native" />
</id>
<property name="title" column="title"/>
<property name="author" column="author"/>
<property name="data" column="data"/>
</class>
</hibernate-mapping>
-
hibernate-mapping
-
類層次:class
-
主鍵:id
-
基本類型:property
-
實體引用類:many-to-one | one-to-one
-
集合:set | list | map | array
-
one-to-many | many-to-many
-
-
子類:subclass | joined-subclass
-
其它:component | any等
-
-
查詢語句:query
-
-
每個hibernate-mapping可以同時定義多個類,但推薦爲每個類都創建一個單獨的映射文件
(1)hibernate-mapping
Hibernate-mapping是hibernate映射文件的根元素
-
schema:指定所映射的數據庫schema的名稱。若指定該屬性,則表明會自動添加該schema前綴
select * from 數據庫名.表名
-
catalog:指定所映射的數據庫catalog的名稱
-
default-cascade(默認:none):設置Hibernate默認的級聯分格
-
default-access(默認:property):指定Hibernate的默認屬性訪問策略。property會使用getter、setter方法訪問屬性,若指定access,則會通過反射訪問成員變量
-
default-lazy(默認:true):默認啓用延遲加載策略
-
auto-import(默認:true):指定是否可以在查詢語句中使用非全限定的類名
-
package:指定一個包前綴,如果在映射文檔中沒有指定全限定的類名,就使用這個作爲包名
(2)class屬性
class元素用於指定類和表的映射
-
name:指定該持久化類的類名
-
table:指定該持久化類映射的表名
-
dynamic-insert(默認:false):若設置爲true,表示當保存一個對象時,會動態生成insert語句,insert語句中僅包含所有取值不爲null的字段
NewsEntity newsEntity = new NewsEntity(); newsEntity.setTitle("hibernate入門"); newsEntity.setData(new Date()); session.save(newsEntity); //title爲null,不會插入title sql語句: Hibernate: insert into hibernate.news (title, data) values (?, ?)
-
dynamic-update(默認:false):若設置爲true,表示當更新一個對象時,會動態生成update語句,update語句中僅包含所有取值需要更新的字段
NewsEntity newsEntity = (NewsEntity)session.get(NewsEntity.class, 20); newsEntity.setAuthor("java23"); newsEntity.setData(new Date()); session.update(newsEntity); //title沒有改變,author和之前一樣 update hibernate.news set data=? where id=?
-
batch-size:指定根據OID來抓取實例時每批抓取的例數
-
lazy:指定是否使用延遲加載
-
multable(默認:true):若設置爲false,等價於所有的property元素的update屬性爲false,表示整個實例不能被更新,默認爲true
(3)映射對象標識符
-
Hibernate使用對象標識符(OID)來建立內存中的對象和數據表中記錄的對應關係。對象的OID和數據表的主鍵對應,Hibernate通過標識符生成器來爲主鍵賦值
-
Hibernate推薦在數據表中使用代理主鍵,即不具備業務含義的字段,代理主鍵通常爲整數類型,因爲整數類型要比字符串類型節省更多的數據庫空間
-
在映射文件中,<id>元素用來設置對象標識符,<generator>子元素用來設定標識符生成器
-
Hibernate提供了標識符生成器接口:IdentifierGenerator,並提供了各種內置實現
(4)id
設定持久化類的OID和表的主鍵的映射
-
name:標識持久化類OID的屬性名
-
column:設置標識屬性所映射的數據表的列名
-
unsaved- value:若設定了該屬性,Hibernate會通過比較持久化類的OID值和該屬性值來區分當前持久化類的對象是否爲臨時對象
-
type:指定Hibernate映射類型
注意:Hibernate映射類型,基本數據類型無法表達null,所以對於持久化類的OID推薦使用包裝類型
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="native" />
</id>
(5)generator
設定持久化類設定標識符生成器
-
主鍵生成策略
標識符生成器 | 描述 |
---|---|
increment | 由Hibernate以遞增方式生成 |
identity | 由底層數據庫生成標識符 |
sequence | 底層數據庫的序列生成標識符,要求數據庫支持序列 |
hilo | Hibernate分局high/low算法生成標識符 |
sequilo | 使用高/低位算法高效的生成long,short,int類型標識符 |
native | 根據底層數據庫對自動生成標識符的方式,自動選擇identity,sequence或hilo |
uuid.hex | 採用128位的UUID算法生成標識符 |
uuid.string | UUID被編碼成一個16字符長的字符串 |
assigned | 由java應用程序負責生成標識符 |
foreign | 使用另外一個相關聯的對象的標識符 |
increment:
-
Hibernate會先讀取對應表中主鍵的最大值,接下來向表中插入記錄時,就在max(id)的基礎上遞增,增量爲1
-
適用範圍:
-
適合所有的數據庫系統
-
適用於只有單個Hibernate應用進程訪問同一個數據庫的場合,在集羣環境下不推薦使用
-
OID必須爲long,int或short類型
-
identity:
-
要求底層數據庫把主鍵定義爲自動增長類型
-
適用範圍:
-
支持自動增長字段類型的數據庫:DB2,Mysql,MSSQLServer,Sybase等
-
OID必須爲long,int或short類型
-
sequence:
-
在持久化一個對象時,先從底層數據庫的序列中獲得一個唯一的標識號,再把它作爲主鍵值
-
適用範圍:
-
支持序列的數據庫:DB2,Oracle等
-
OID必須爲long,int或short類型
-
hilo:
-
按照一種high/low算法生成標識符,它從數據庫的特定表的字段中獲取high值
<id name="id">
<generator class="hilo">
<param name="table">hl_table</param>
<param name="column">next_value</param>
<!-- 每次增加的id(默認爲0) 1/12/23 -->
<param name="max_lo">10</param>
</generator>
</id>
native:
-
適用範圍:
-
能根據底層數據庫系統的類型,自動選擇合適的標識符生成器,因此很適合與跨數據庫平臺開發
-
OID必須爲long,int或short類型
-
(6)Property
property元素用於指定類的屬性和表的字段的映射
-
name:指定該持久化類的屬性的名字
-
column:指定與類的屬性映射的表的字段名,如果沒有設置該屬性,將直接使用類的屬性名作爲字段名
-
type:指定Hibernate映射類型
-
not-null:若該屬性爲true,表名不允許爲null,默認爲false
-
access:指定Hibernate的默認的屬性訪問策略。默認爲property,若指定filed,則通過反射訪問成員變量
-
unique:設置是否爲該屬性所映射的數據列添加唯一約束
-
index:指定一個字符串的索引名稱
<property name="author" type="java.lang.String" index="news_index">
<column name="AUTHOR" />
</property>
-
length:指定該屬性所映射數據列的字段的長度
-
scale:指定該屬性鎖映射數據列的小樹數位
-
formula:設置一個SQL表達式,Hibernate將根據它來計算出派生屬性的值
-
formula="sql"
-
sql表達式中的列名和表名都應該和數據庫對應,而不是和持久化對象的屬性對應
-
如果需要在formula屬性中使用參數,直接使用 where cur.id=id形式,其中id就是參數,和當前持久化對象的id屬性對應的列的id值將被作爲參數傳入
-
<!-- 映射派生屬性 -->
<property name="desc" formula="(SELECT concat(author, ': ', title) FROM NEWS n WHERE n.id = id)"></property>
(7)java類型與SQL類型之間的對應關係
Hibernate映射類型 | Java類型 | SQL類型 | 大小 |
---|---|---|---|
integer/int | java.lang.Integer/int | integer | 4字節 |
long | java.lang.Long/long | bigint | 8字節 |
short | java.lang.Short/short | smallint | 2字節 |
byte | java.lang.Byte/byte | tinyint | 1字節 |
float | java.lang.Float/float | float | 4字節 |
double | java.lang.Double/double | double | 6字節 |
big_decimal | java.math.BigDecimal | mumeric | |
character | java.lang.Character/char | char(1) | 定長字符 |
string | java.lang.String | varchar | 變長字符 |
boolean | java.lang.Boolean/boolean | bit | 布爾類型 |
date | java.util.Date/java.sql.Date | date | 日期 |
timestamp | java.util.Date/java.sql.Timestamp | timestamp | 日期 |
calandar | java.util.Calendar | timestamp | 日期 |
calandar_date | java.util.Calendar | date | 日期 |
binary | byte[] | blob | blob |
text | java.lang.String | text | clob |
serializable | 實現java.io.Serializable接口的類 | blob | blob |
clob | java.sql.Clob | clob | clob |
blob | java.sql.Blob | blob | blob |
class | java.lang.Class | varchar | 定長字符 |
locale | java.util.Locale | varchar | 定長字符 |
timezone | java.util.TimeZone | varchar | 定長字符 |
currency | java.util.Currency | varchar | 定長字符 |
-
以下情況下必須顯示指定Hibernate映射類型
-
一個Java類型可能對應多個Hibernate映射類型。例如:如果持久化類的屬性爲java.util.Date類型,對應的Hibernate映射類型可以是date,time或timestamp。此時必須根據對應的數據表的字段的SQL類型,來確定Hibernate映射類型
-
-
java大對象的Hibernate映射
-
java中,提供了Clob和Blob類型,對應SQL中的CLOB和BLOB類型。CLOB表示字符串大對象,BLOB表示二進制對象
-
Mysql不支持標準SQL的CLOB類型,在Mysql中,用text,mediumtext及longtext類型表示長文本數據
-
實際上在Java中處理長度超過255的字符串,使用String更方便
<!-- 映射大對象 --> <!-- 若希望精確映射 SQL 類型, 可以使用 sql-type 屬性. --> <property name="content"> <column name="CONTENT" sql-type="mediumtext"></column> </property> <property name="image"> <column name="IMAGE" sql-type="mediumblob"></column>
-