Hibernate開發(fā)文檔
一.基本概念:
SessionFactory :它是單個(gè)數(shù)據(jù)映射表經(jīng)編譯后的內(nèi)存鏡像,是線程安全的,是生成session的工廠.該對(duì)象可以在進(jìn)程或集群的級(jí)別上,為那些事務(wù)之間可以重用的數(shù)據(jù)提供可選的二級(jí)緩存.
Session:它是應(yīng)用程序與持久存儲(chǔ)層之間交互操作的一個(gè)單線程對(duì)象.所有的持久化對(duì)象必須在session管理下才可以進(jìn)行持久化操作.此對(duì)象生存期很短,它隱藏了JDBC連接,也是Transaction的工廠.Session對(duì)象有一個(gè)一級(jí)緩存,顯式執(zhí)行flush之前,所有持久化操作的數(shù)據(jù)都緩存在Session對(duì)象處.
持久態(tài):系統(tǒng)創(chuàng)建的pojo對(duì)象,一旦與Session關(guān)聯(lián)起來并對(duì)應(yīng)成數(shù)據(jù)庫(kù)中的記錄,對(duì)其所有的操作都相當(dāng)于對(duì)數(shù)據(jù)庫(kù)的操作
暫態(tài)/脫管態(tài):暫態(tài)指新創(chuàng)建的未與Session關(guān)聯(lián)的的對(duì)象,其可能是未持久化的對(duì)象;脫管態(tài)指持久態(tài)的對(duì)象因Session關(guān)閉導(dǎo)致臨時(shí)失去持久態(tài)的對(duì)象
事務(wù):代表一次原子操作,具有數(shù)據(jù)庫(kù)事務(wù)的概念.某些情況下,一個(gè)Session之內(nèi)可能包含多個(gè)Transaction對(duì)象.雖然事務(wù)操作是可選的,但是所有持久化操作都應(yīng)該在事務(wù)管理下進(jìn)行,即使是只讀操作.
連接提供者:ConnectionProvider,是生成jdbc連接的工廠,同時(shí)具備連接池的作用.它通過抽象將應(yīng)用從底層的Datasource或DriverManager隔離開.無需直接訪問
事務(wù)工廠:它是生成Transaction對(duì)象實(shí)例的工廠,無需直接訪問
二.使用須知;
1.配置文件
①hibernate.properties
Configuration cfg=new Configuration()
.addResource("Item.hbm.xml")
.addResource("Bid.hbm.xml");
還可以
Configuration cfg=new Configuration()
.addClass(lee.Item.Class)
.addClass(lee.Bid.Class);
這種可以讓Hibernate自動(dòng)根據(jù)持久化類來搜索配置文件,但是應(yīng)保證配置文件和pojo同一目錄下
②使用 hibernate.cfg.xml
這種方法可以直接使用
Configuration cfg=new Configuration().configure()
③使用Configuration cfg=new Configuration().addClass("").setProperty("","")
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="hibernate.connection.password">32147</property>
<property name="hibernate.connection.url">
jdbc:mysql://localhost:3306/hibernate
</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">update</property>
<mapping resource="News.hbm.xml" />
</session-factory>
</hibernate-configuration>
2.連接池:
<!—連接池-->
<property name="hibernate.c3p0.max_size">20</property>
<property name="hibernate.c3p0.min_size">1</property>
<property name="hibernate.c3p0.timeout">5000</property>
<!—緩存Statement的數(shù)量-->
<property name="hibernate.c3p0.max_statements">100</property>
<property name="hibernate.c3p0.idle_test_period">3000</property>
<property name="hibernate.c3p0.acquire_increment">2</property>
<property name="hibernate.c3p0.validate">true</property>
3.JNDI 無需hibernate自己管理數(shù)據(jù)源的時(shí)候使用,雖然使用JNDI數(shù)據(jù)源,仍然需要指定數(shù)據(jù)庫(kù)的方言,盡管數(shù)據(jù)庫(kù)方言是可選de.
<!--配置JNDI數(shù)據(jù)源的JNDI名-->
<property name="connection.datasource">java:comp/env/jdbc/dstest</property>
<!—配置連接庫(kù)的方言-->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
4.其他配置屬性:
①hibernate.show_sql 是否輸出sql
②hibernate.jdbc.fetch_size 指定jdbc抓取數(shù)量的大小,
③hibernate.jdbc.batch_size 指定Hibernate使用JDBC批量更新的大小,它可以接受一個(gè)整數(shù)值,建議5到三十
④hibernate.connection.autocommit 設(shè)置是否自動(dòng)提交,通常不建議打開
⑤hibernate.hbm2ddl.auto 設(shè)置當(dāng)創(chuàng)建SessionFactory時(shí),是否根據(jù)映射文件自動(dòng)建立數(shù)據(jù)庫(kù)表.該屬性可以為:update create create-drop
三.持久化類的要求:
1.getter setter 等
2.一個(gè)無參構(gòu)造器
3.一個(gè)標(biāo)示屬性
4.如果使用一個(gè)有public final方法的類,必須通過設(shè)置lazy="false"來禁用代理
5.重寫equals() hashCode()方法(如果需要把pojo類的實(shí)例放入Set中的時(shí)候) 重寫時(shí),通常建議使用業(yè)務(wù)鍵值來實(shí)現(xiàn).
6.狀態(tài)轉(zhuǎn)換:
//////
News n=new News();
n.setName("");
sess.save(n)
//////
News n=Session.load(News.class, new Integer(pk));
n.setTitle("biaoti");
////
News n=Session.load(News.class, new Integer(pk));
Session.delete(n);
四.映射文件
1.樣本
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="lee">
<class name="Person">
<id name="id" column="personid">
<generator class="identity"/>
</id>
<property name="name"/>
<property name="age"/>
</class>
</hibernate-mapping>
2.主鍵生成器
increment 對(duì)long short int數(shù)據(jù)列生成自增長(zhǎng)主鍵
identity 對(duì)如SQL Server,MySql等支持自增長(zhǎng)列的數(shù)據(jù)庫(kù)且數(shù)據(jù)列的類型long int short
sequence 對(duì)如Oracle DB2等支持sequence的數(shù)據(jù)庫(kù)且數(shù)據(jù)列的類型為long int short
uuid 采用128-位UUID算法生成唯一的字符串主鍵
3.映射集合屬性
List
<list name="schools" table="school">
<key column="personid" not-null="true"/>
<list-index column="list_order"/>
<element type="string" column="school_name"/>
</list>
Set
<set name="shools" table="shool">
<key column="personid" not-null="true"/>
<element type="string" column="school_name" not-null="true"/>
</set>
Bag
<bag name="shools" table="shool">
<key column="personid" not-null="true"/>
<element type="string" column="school_name" not-null="true"/>
</bag>
Map
<map name="scores" table="score">
<key column="personid" not-null="true"/>
<map-key column="xueke" type="string"/>
<element type="float" column="mark"/>
</map>
4.組件及復(fù)合主鍵映射
①"屬性組件"組件為pojo的一個(gè)普通屬性類 private Name name Name(first,last)
<component name="name" class="Name" unique="true">
<property name="first"/>
<property name="last"/>
</component>
②"集合元素組件"組件為L(zhǎng)ist等集合的一個(gè)元素 private List<School> schools
School(name, address)
<list name="schools" table="school">
<!--映射關(guān)聯(lián)外鍵-->
.<key column="personid" not-null="true"/>
<list-index column="list_order">
<composite-element class="School">
<property name="name">
<property name="address">
</composite-element>
③"屬性組件主鍵" private Name name (用name做主鍵 ,不推薦) Name(firstName,lastName)
<composite-id name="name" class="Class">
<!-- key-property元素確定標(biāo)識(shí)屬性包含的屬性-->
<key-property name="firstName">
<kry-property name="lastName">
</composite-id>
④"復(fù)合主鍵" private String firstName ;private String lastName;
<composite-id>
<!-- key-property元素映射復(fù)合主鍵的每個(gè)元素-->
<key-property name="firstName">
<kry-property name="lastName">
</composite-id>
5.關(guān)聯(lián)關(guān)系
單向還是雙向:
\單向還是雙向取決于對(duì)關(guān)聯(lián)端的訪問要求,從根本上來講雙向和單向是沒有區(qū)別的,舉個(gè)子如,老師找學(xué)生;學(xué)生找老師;老師找學(xué)生同時(shí)學(xué)生也找老師.單向也好,雙向也好,都指同一個(gè)關(guān)聯(lián)關(guān)系
一對(duì)多還是多對(duì)一到底怎么看:
㈠單向關(guān)系
1. 單向1-1
1.1基于外鍵 many-to-one 相當(dāng)于 property,區(qū)別是該元素映射的關(guān)聯(lián)的持久化類
<many-to-one name="address" type ="Address" column="addressid" unique="true" />
1.2基于外鍵 有連接表的 這里用join顯式確定連接表
<join table="join_table">
<key column="personid"/>
<many-to-one name="address" unique="true"/>
</join>
1.3基于主鍵
<id name="personid">
<generator class="foreign">
<param name="property">address</param>
</generator> </id>
<!--constrainted表明該類的主鍵根據(jù)關(guān)聯(lián)類生成-->
<one-to-one name="address" constrained="true"/>
2.單向N-1
2.1 無連接表
<many-to-one name="address" column="addressid"/>
2.2有連接表
<join table="join_table">
<key column="personid"/>
<many-to-one name="address" />
</join>
3.單向1-N
3.1 無連接表的 one-to-many和element類似
<set name="address">
<key column="personid"/>
<one-to-many class="Address"/>
</set>
3.2 有連接表 many-to-many 表明要N-N或1-N,unique=true表明這里是1-N關(guān)系
<set name="address">
<key column="personid"/>
<many-to-many class="Address" unique="true"/>
</set>
4.單向N-N
這與單向1-N沒有區(qū)別,配置文件只需將unique="true"改為unique="false"或去掉
<set name="address">
<key column="personid"/>
<many-to-many class="Address" unique="false"/>
</set>
㈡雙向關(guān)系
1.雙向1-N
1.1無連接表
注意: 兩個(gè)配置文件都應(yīng)該指定外鍵,且不應(yīng)省略.
Person.hbm.xml
<set name="address">
<key column="personid"/>
<one-to-many class="Address"/>
</set>
Address.hbm.xml
<many-to-one name="person" column="personid">
1.2有連接表
注意:1.兩遍確定連接表的table屬性值應(yīng)該相等,且不可以省略
2.兩遍都制定了兩個(gè)外鍵列,一定要保證兩邊映射文件的外鍵列名對(duì)應(yīng)相同
Person.hbm.xml
<set name="address" table="personAddress">
<key column="personid"/>
<many-to-many class="Address" unique="true" column="addressid"/>
</set>
Address.hbm.xml //optional表示是否可選
<join table="PersonAddress" inverse="true" optional="true">
<many-to-one name="person" column="personid">
2.雙向N-N
雙向多對(duì)多的兩邊都要指定table 和外鍵列的列名 且它們都要一致
Person.hbm.xml
<set name="addresses" table="jointable">
<key column="personid"/>
<many-to-many column="addressid" class="Address"/>
</set>
Address
<set name="persons" table="jointable">
<key column="addressid"/>
<many-to-many column="personid" class="Person">
</set>
3.雙向1-1
3.1基于外鍵
注意: 基于外鍵的雙向1-1,外鍵可以放在任一端,當(dāng)然需要增加many-to-one屬性.而另一端就需要使用one-to-one元素,為了不讓系統(tǒng)再為本表增加一列,而是使用外鍵關(guān)聯(lián)可以用property-ref屬性引用關(guān)聯(lián)類的自身屬性.注意:one-to-one映射關(guān)聯(lián)屬性,不會(huì)創(chuàng)建外鍵列.
Person.hbm.xml
<one-to-one name="address" property-ref="person"/>
Address.hbm.xml
<many-to-one name="person" class="Person" unique="true"/>
3.2基于主鍵
Person.hbm.xml
<one-to-one name="address" />
Address.hbm.xml
<generator class="foreign">
<param name="property">address</param></generator>
< one-to-one name="person" constrained="true"/>
3.3基于外鍵的強(qiáng)制連接表(不推薦)
Person.hbm.xml
<join table="personaddress" optional="true">
<key column="personid" unique="true"/>
<many-to-one name="address" column="addressid" not-null="true" unique="true">
</join>
Address.hbm.xml
<join table="personaddress" optional="true" inverse="true">
<key column=" addressid" unique="true"/>
<many-to-one name="person" column=" personid" not-null="true" unique="true"/>
</join>
length 屬性值得是字符個(gè)數(shù),這個(gè)與數(shù)據(jù)庫(kù)是不同的