一般.hbm.xml文件如下面:
1 <?xml version="1.0"?> 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 4 <!-- Generated 2014-9-29 8:46:32 by Hibernate Tools 3.4.0.CR1 --> 5 <hibernate-mapping> 6 <class name="com.jeremy.hibernate.app.News" table="NEWS"> 7 <id name="id" type="java.lang.Integer"> 8 <column name="ID" /> 9 <generator class="native" /> 10 </id> 11 <property name="title" type="java.lang.String"> 12 <column name="TITLE" /> 13 </property> 14 <property name="author" type="java.lang.String"> 15 <column name="AUTHOR" /> 16 </property> 17 <property name="date" type="java.util.Date"> 18 <column name="DATE" /> 19 </property> 20 </class> 21 </hibernate-mapping>
<Hibernate-mapping>標簽的屬性如下:
1)package:指定一個包前綴,如果在映射文檔中(就是在class標簽的那么屬性里沒有指定全類名)沒有指定全限定的類名,就使用這個作為包名,
2)schema:數據庫schema的名稱
3)catalog:數據庫catalog的名稱
4)default-cascade:默認的級聯風格,默認為none
5)default-access:Hibernate用來訪問屬性的策略
6)default-lazy:指定了此屬性,未明確注明lazy屬性的Java屬性和集合類,Hibernate會采取的默認使用這個屬性加載風格,默認為true
7)auto-import:指定我們是否可以在查詢語言中使用非全限定的類名,默認為true,如果項目中有兩個同名的持久化類,則最好在這兩個類的對應的映射文件中配置為false
Hibernate的子標簽class標簽:
class 元素用於指定類和表的映射
name:指定該持久化類映射的持久化類的類名
example:<class name="com.jeremy.hibernate.example.News" table="NEWS">
table:指定該持久化類映射的表名, Hibernate 默認以持久化類的類名作為表名
example:<class name="com.jeremy.hibernate.example.News" table="NEWS">
dynamic-insert: 若設置為 true, 表示當(調用Session的save()方法時)保存一個對象時, 會動態生成 insert 語句, insert 語句中僅包含所有取值不為 null 的字段. 默認值為 false
Example:這個跟dynamic-update一個意思
dynamic-update: 若設置為 true, 表示當(調用對象的set()方法)更新一個對象時, 會動態生成 update 語句, update 語句中僅包含所有取值需要更新的字段. 默認值為 false
Example:當我們調用對象的set()方法時,Hibernate會自動幫我們發送更新語句給數據庫是吧,但是有沒有注意到發送給數據庫語句有什么不同呢?下面看一下
@Test public void TestDymainUpdate(){ News news=(News) session.get(News.class, 1); news.setAuthor("jeremyJeremy"); }
這個是我測試的代碼,當我運行這代碼時控制台出現了下面的代碼:
Hibernate: select news0_.ID as ID1_0_0_, news0_.TITLE as TITLE2_0_0_, news0_.AUTHOR as AUTHOR3_0_0_, news0_.DATE as DATE4_0_0_ from NEWS news0_ where news0_.ID=? Hibernate: update NEWS set TITLE=?, AUTHOR=?, DATE=? where ID=?
select部分是我調用的Session的get()方法,Hibernate自動發送的,
update部分是我調用了對象的set()方法觸發的是吧,但是有沒有注意到,我的測試代碼里只更新一個Author屬性吖,Hibernate為啥會幫我把其它屬性也更新吖,雖然數據沒變,但是是不是有點低效率吖,我只想我更新那個屬性,Hibernate就幫我更新那個屬性,所以這里就要用到class標簽的dynamic-update屬性了:當我把這屬性值改為TRUE后:
Hibernate自動發送的語句:
Hibernate: update NEWS set AUTHOR=? where ID=?
select-before-update:設置 Hibernate 在更新某個持久化對象之前是否需要先執行一次查詢. 默認值為 false
這個有在我一篇文章詳細介紹:http://www.cnblogs.com/jeremy-blog/p/4000419.html
batch-size:指定根據 OID 來抓取實例時每批抓取的實例數.
lazy: 指定是否使用延遲加載.
mutable: 若設置為 true, 等價於所有的 <property> 元素的 update 屬性為 false, 表示整個實例不能被更新. 默認為 true.
discriminator-value: 指定區分不同子類的值. 當使用 <subclass/> 元素來定義持久化類的繼承關系時需要使用該屬性(不建議使用)
class標簽的子標簽
<id>標簽:在對象-關系映射文件中, <id> 元素用來設置對象標識符. <generator> 子元素用來設定標識符生成器.
<id name="id" type="java.lang.Integer">---指定類中的ID屬性和類型
<column name="ID" />-----數據庫中列名
<generator class="native" />-----指定ID的自動生成方式,(例如自增,或者隨機生成)
</id>
generator的class屬性:
詳細解析:
increment 標識符生成器由 Hibernate 以遞增的方式為代理主鍵賦值
Hibernate 會先讀取 NEWS 表中的主鍵的最大值, 而接下來向 NEWS 表中插入記錄時, 就在 max(id) 的基礎上遞增, 增量為 1.
適用范圍: 由於 increment 生存標識符機制不依賴於底層數據庫系統, 因此它適合所有的數據庫系統
適用於只有單個 Hibernate 應用進程訪問同一個數據庫的場合, 在集群環境下不推薦使用它 OID 必須為 long, int 或 short 類 型, 如果把 OID 定義為 byte 類型, 在運行時會拋出異常
模擬increment生成器產生問題的過程:
@Test public void testIncrement() throws InterruptedException{ News news1=new News("AA","AAAAA",new Date()); session.save(news1); Thread.sleep(5000); }
把上面的代碼連續運行兩次就相當於有連續兩次的客戶訪問我的數據庫,就是說同時多人訪問我數據庫時,大家讀取到的max值都是一樣的吧,所以插入的時候ID值會並發出主鍵重復的問題,所以在實際開發中不能應用這種方式來生成ID
還有很多主鍵生成器,我忽略一下,因為實在太多了
下面介紹一下class標簽的子標簽property
<property>:元素用於指定類的屬性和表的字段的映射(關聯起來)
屬性:
name:指定該持久化類的屬性的名字 column:指定與類的屬性映射的表的字段名. 如果沒有設置該屬性, Hibernate 將直接使用類的屬性名作為字段名. type:指定 Hibernate 映射類型. Hibernate 映射類型是 Java 類型與 SQL 類型的橋梁. 如果沒有為某個屬性顯式設定映射類型,Hibernate 會運用反射機制先識別出持久化類的特定屬性的 Java 類型, 然后自動使用與之對應的默認的 Hibernate 映射類 型.(例如Java.lang.String->String->varchar)
update:設置該列是否可以被修改,默認是TRUE,設置為FALSE時不可以修改列的值, not-null:若該屬性值為 true, 表明不允許為 null, 默認為 false access:指定 Hibernate 的默認的屬性訪問策略。 默認值為 property, 即使用 getter, setter 方法來訪問屬性. 若指定 field, 則 Hibernate 會忽略 getter/setter 方法, 而通過反射訪問成員變量 unique: 設置是否為該屬性所映射的數據列添加唯一約束.
index: 指定一個字符串的索引名稱.當系統需要 Hibernate 自動建表時, 用於為該屬性所映射的數據列創建索引, 從而加快該數據列的查詢
length: 指定該屬性所映射數據列的字段的長度
scale: 指定該屬性所映射數據列的小數位數, 對 double, float, decimal 等類型的數據列有效.
formula:設置一個 SQL 表達式,Hibernate 將根據它來計算出派生屬性的值.派生屬性:並不是持久化類的所有屬性都直接和表的字段匹配,
持久化類的有些屬性的值必須在運行時通過計算才能得出來, 這種屬性稱為派生屬性
Example:例如下面的的desc列是有author列+“:”+title列組成的,那咋們可以這樣配置formula
<!-- 映射派生屬性 -->
<property name="desc" formula="(SELECT concat(author, ': ', title) FROM NEWS n WHERE n.id = id)"></property>
表間(對象和對象之間)映射關系配置說明
配置步驟:
①:分析1端和n端
②:在1端插入n端的集合屬性
③:在n端插入一端的對象屬性
④:注明關系在那一段維護
單向一對一:
one-to-one:one-to-one<--->many-to-one
example:IDCard<-->person
①IDCard是一端,Person也是1端
②在IDCard一端插入另一個一端的對象屬性:--->private person person
③在person一端插入另一個一端的對象屬性:--->private IDCard IDCard
④指定維護關系:在維護方指定被維護方的外鍵--<many-to-one name="idCard" unique="true"></many-to-one>
單向一對多:
one-to-many<--->many-to-one
many-to-many<-->many-to-many>