天天看點

Hibernate知識點 001

軟體開發的分層思想:

三層架構:

 資料表現層

 業務邏輯層

 資料持久層

SUN的桌面應用

 Swing AWT

 普通Java類

 JDBC

SUN的WEB基本應用

 JSP

 普通Servlet

 JDBC

SUN的WEB進階應用

 JSF

 SessionBean

 Persistence

WEB國内流行開源

 Struts

 Spring

 Hibernate

一、 對象持久化的理論

1.對象持久化:記憶體中的對象轉存到外部持久裝置上,在需要的時候還可以恢複。

2.對象持久化的原因(目标):

實體:

1) 記憶體不能持久,需要在硬碟上持久儲存 //(實體上,實體的都不是根本原因)

2) 記憶體容量有限,需要在容量更大的硬碟上儲存

應用:

3) 共享(Internet的本質:資訊的收集、整理、釋出) //最重要的原因

4) 檢索(大規模) //也很重要

5) 管理(備份、安全)

3.怎樣進行對象持久化?(僅從JAVA方面講)

實體:

1) 對象序列化

2) DB技術(JDBC 資料庫)

4.怎樣利用資料庫做對象持久化?

1) JDBC

優點:功能完備、理論上效率高

缺點:複雜(難)、代碼量大、面向R(過程;二維表關系)

2) EJB 僅講Entity Bean

優點:封裝JDBC

缺點:更複雜的API、重量級(侵入式)、功能不完備、難共享

缺點的後果:開發周期長、測試困難、面向過程

以上是 2.0之前的版本,但 3.0跟Hibernate基本一樣

3) ORM 輕量級架構(Hibernate)

現階段最佳的持久化工具:文檔齊全、服務很好、工業标準、大量應用、易學

優點:封裝JBDC、簡單的API、輕量級(隻做持久化)(用類庫)、PO(持久對象)->POJO(純JAVA)、開源

缺點:不夠JDBC靈活

5.結論:

1)對象持久化是必須的

2)必須使用DB來實作

3)Hibernate必須的(現階段最佳選擇)

開源工具的通常問題:1.文檔不全;2.服務不全;3.标準化不夠

而Hibernate避免了所有這些問題

二、 ORM和Hibernate的相關知識(了解)

1) ORM:Object Relational Mapping

對象-關系映射實作了面向對象世界中對象到關系資料庫中的表的自動的(和透明的)持久化,使用中繼資料(meta data)描述對象與資料庫間的映射。

2) Hibernate是非常優秀、成熟的O/R Mapping架構。它提供了強大的對象和關系資料庫映射以及查詢功能。

規範:

1.一個映射檔案對應一個持久類(一一對應)

2.映射檔案的名字和它所描述的持久類的名字保持一緻

3.映射檔案應該與它所描述的類在同一包中

po -> (pojo)

-> oid(唯一,中性)

-> getters/setters

-> 構造方法

三、Hibernate核心API(了解)

Configuration類:

Configuration對象用于配置和啟動Hibernate。Hibernate應用通過Configuration執行個體來指定對象-關系映射檔案的位置或者動态配置Hibernate的屬性,然後建立SessionFactory執行個體。

SessionFactory接口:

一個SessionFactory執行個體對應一個資料存儲源。應用從SessionFactory中擷取Session執行個體。

1)它是線程安全的,這意味着它的一個執行個體能夠被應用的多個線程共享。

2)它是重量級的,這意味着不能随意建立或者銷毀,一個資料庫隻對應一個SessionFactory。

通常建構SessionFactory是在某對象Bean的靜态初始化代碼塊中進行。

如果應用隻是通路一個資料庫,隻需建立一個SessionFactory執行個體,并且在應用初始化的時候建立該執行個體。

如果應用有同時通路多個資料庫,則需為每個資料庫建立一個單獨的SessionFactory。

Session接口:

是Hibernate應用最廣泛的接口。它提供了和持久化相關的操作,如添加,删除,更改,加載和查詢對象。

1)它是線程不安全的,是以在設計軟體架構時,應盡量避免多個線程共享一個Session執行個體。

2)Session執行個體是輕量級的,這意味着在程式可以經常建立和銷毀Session對象,

例如為每個客戶請求配置設定單獨的Session執行個體。

原則:一個線程一個Session;一個事務一個Session。

Transaction接口:

是Hibernate的事務處理接口,它對底層的事務接口進行封裝。

Query和Criteria接口:

這兩個是Hibernate的查詢接口,用于向資料庫查詢對象,以及控制執行查詢的過程。

Query執行個體包裝了一個HQL查詢語句。

Criteria接口完全封裝了基于字元串形式的查詢語句,比Query接口更面向對象。Criteria更擅長于執行動态查詢。

補充:find方法也提供資料查詢功能,但隻是執行一些簡單的HQL查詢語句的快捷方式(已過時),遠沒有Query接口強大!

四、Hibernate開發步驟:(重點:必須掌握)

開始:(設定環境變量和配置)

在myeclipse裡導入Hibernate的檔案包(包括各資料庫的驅動和其他的jar包,對版本敏感,注意各版本的相容)

按hibernate規範編寫名字為hibernate.cfg.xml檔案(預設放在工程檔案夾下)

步驟一:設計和建立資料庫表

可以用Hibernate直接生成映射表。

Oracle裡建表: create table t_ad (oid number(15) primary key,

ACTNO varchar(20) not null unique,BALANCE number(20));

步驟二:持久化類的設計

POJO---- POJO 在Hibernate 語義中了解為資料庫表所對應的Domain Object。(此類中隻含有屬性、構造方法、get/set方法)

這裡的POJO就是所謂的“Plain Ordinary Java Object”,字面上來講就是無格式普通Java 對象, 簡單的可以了解為一個不包含邏輯代碼的值對象(Value Object 簡稱VO)。

步驟三:持久化類和關系資料庫的映射

編寫*.hbm.xml檔案---該檔案配置持久化類和資料庫表之間的映射關系

Xml代碼 

<class name=“POJO的類全路徑”  table=“對應的庫表名”     //這兩項一定要配置,其它的都可以不配置 discriminator-value=“discriminator_value”   //區分不同子類的值,多态時使用。預設與類名一樣    

dynamic-update=“true | false” //是否動态更新SQL。false:每次都更新所有屬性;true:隻更新修改的    

dynamic-insert=“true | false” //是否動态插入SQL。false:每次都插入所有屬性;true:隻插入非空的    

select-before-update=“true | false” //是否在update前查詢對象是否被修改過,修改過才update    

polymorphism=“implicit | explicit”  //設定多态是顯性(explicit)的還是隐性(implicit)的    

where=“查詢時使用的SQL的條件子句”  //查詢時使用的SQL的條件子句    

lazy=“true | false” //設定延遲加載政策    

/>   

一個實體對應一個xml檔案,元件用id,非元件用property。

*.hbm.xml檔案樣闆:

Xml代碼 

       <?xml version="1.0"?>    

       <!DOCTYPE hibernate-mapping PUBLIC     

           "-//Hibernate/Hibernate Mapping DTD 3.0//EN"    

           "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">    

<!--package指檔案所在的包名 -->  

       <hibernate-mapping package="com.tarena.ebank.biz.entity">    

        <!-- name:POJO類的名; table資料庫裡對應的表名-->  

          <class name="Account" table="student">    

    <!-- OID:(唯一,中性)表自動生成的(需要另外添加hilo表) -->  

             <id name="oid" column="OID">    

                <generator class="hilo">    

                   <param name="table">t_hi</param>    

                   <param name="column">hi</param>    

             </generator></id>    

             <property name="actNo" column="ACTNO" unique="true" not-null="true"/>    

             <property name="bal" column="BALANCE" not-null="true"/>    

          </class>    

       </hibernate-mapping> 

步驟四:Hibernate配置檔案

hibernate.cfg.xml或hibernate.properties

1.需要配置那些資訊:持久化映射,方言,特性,登陸資訊

多數使用預設的設定。

A、dialect:方言,就是拼驅動程式和SQL語句。每種資料庫對應一種方言其實就是指定了用那一種資料庫。

Oracle資料庫方言:org.hibernate.dialect.OracleDialect

MySql資料庫方言:org.hibernate.dialect.MySQLDialect

B、Object Persistence:對象持久化。把記憶體中的資料儲存到一個永久的媒體中,比如說資料庫。

C、ORM:對象關系映射,是一個自動的過程

注:持久對象與臨時對象最大的差別是有沒有資料庫id辨別。

2.hibernate.cfg.xml的樣闆:

Xml代碼 

<?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="connection.url">jdbc:mysql://localhost:3306/test</property>    

  <property name="connection.driver_class">com.mysql.jdbc.Driver</property>    

  <property name="connection.username">root</property>    

  <property name="connection.password">password</property>    

  <!-- 自動建表語句:create覆寫舊表,update自動更新,none不理會 -->    

  <property name="hbm2ddl.auto">update</property>     

  <!-- 是否在控制台上列印SQL(Hibernate把語句轉化為SQL語句),預設false-->    

  <property name="show_sql">true</property>    

  <!-- 緩存政策,資料量不大可不寫  -->    

  <property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>    

  <property name="cache.use_query_cache">false</property>    

  <property name="cache.use_second_level_cache">false</property>    

  <!-- 不同資料庫使用的SQL選擇 -->    

  <property name="dialect">org.hibernate.dialect.MySQLDialect</property>    

  <property name="myeclipse.connection.profile">mysql</property>    

  <!-- 連接配接池配置,練習時不寫,使用預設的 -->    

  <property name="connection.pool_size">1</property>    

  <!--決定是采用thread或jta或自定義的方式來産生session,練習時不寫,使用預設的  -->    

  <property name="current_session_context_class">thread</property>    

  <!-- *.hbm.xml檔案路徑,各關聯表要一同寫上 -->    

  <mapping resource="many_to_one/vo/Customer.hbm.xml" />    

  <mapping resource="com/tarena/ebank/biz/entity/Order.hbm.xml" />    

</session-factory>    

</hibernate-configuration>  

步驟五:使用Hibernate API

Java代碼

//讀取Hibernate.cfg.xml配置檔案,并讀到記憶體中為後續操作作準備    

Configuration config = new Configuration().configure();    

//SessionFactory緩存了生成的SQL語句和Hibernate在運作時使用的映射中繼資料。    

SessionFactory sessionFactory = config.buildSessionFactory();    

//Session是持久層操作的基礎,相當于JDBC中的Connection。    

Session session = sessionFactory.openSession();    

try{     

原子性,必須捕捉異常。所有事務都放在這一代碼塊裡。    

    //操作事務時(增、删、改)必須顯式的調用Transaction(預設:autoCommit=false)。    

    Transaction tx = session.beginTransaction();    

    for(int i=0; i<=1000; i++){    

      Student stu = new Student(...);    

      session.save(stu);//set value to stu    

      //批量更新:為防止記憶體不足,分成每20個一批發送過去。     

      if(i%20==0){session.flush();session.clear();}//不是大批量更新,則不需要寫這一行    

      //預設時,會自動flush:查詢之前、送出時。    

    } tx.commit();//送出事務,Hibernate不喜歡抛異常,如有需要,自己捕捉。    

    //查詢方法。如果有必要,也可以用事務(調用Transaction)     

    String hql = "from Student s where s.stuNo like ? and s.Sal > ?";//Student是類而不是表    

    List list = session.createQuery(hql)    

                       .setString(0, "a00_").setDouble(1, 3000.0)//設定HQL的第一二個問号取值    

                       .list();//Hibernate裡面,沒有傳回值的都預設傳回List    

    StringBuffer sb = new StringBuffer();    

    for(Student st :(List<Student>)list){//(List<Student>)強制類型轉換    

      sb.append(st.getOid()+"  "+st.getName()+"/n");//拿到Student類裡的屬性    

    }System.out.print(sb.toString());//直接列印sb也可以,它也是調用toString,但這樣寫效率更高    

} catch (HibernateException e) {    

    e.printStackTrace();    

    session.getTransaction().rollback();//如果事務不成功,則rollback    

} finally {    

    session.close();//注意關閉順序,session先關,Factory最後關(因為它可以啟動多個session)     

    sessionFactory.close();//關閉SessionFactory,雖然這裡沒看到它,但在HbnUtil裡開啟了。    

五、 Hibernate主鍵政策(上面的步驟三的一部分)

<id><generator class=“主鍵政策” /></id>

主鍵:在關系資料庫中,主鍵用來辨別記錄并保證每條記錄的唯一性(一般可保證全資料庫唯一)。必須滿足以下條件:

1)不允許為空。

2)不允許主鍵值重複。

3)主鍵值不允許改變。

1.自然主鍵:以有業務含義的字段為主鍵,稱為自然主鍵。

優點:不用額外的字段。

缺點:當業務需求發生變化時,必須修改資料類型,修改表的主鍵,增加了維護資料庫的難度。

2.代理主鍵:增加一個額外的沒有任何業務含義的一般被命名為ID的字段作為主鍵。

缺點:增加了額外字段,占用部分存儲空間。

優點:提高了資料庫設計的靈活性。

Hibernate用對象辨別(OID)來區分對象:

Student stu = (Student)session.load(Student.class,101); //這代碼加載了OID為101的Student對象

Hibernate推薦使用代理主鍵,是以Hibernate的OID與代理主鍵對應,一般采用整數型,包括:short、int、long。

1、主鍵生成政策: (Hibernate支援多種主鍵生成政策)

generator節點中class屬性的值:

1) assigned:assigned:由使用者自定義ID,無需Hibernate或資料庫參與。是<generator>元素沒有指定時的預設生成政策。

<id name="id" column="id"><generator class="assigned"/></id>

2) hilo:通過hi/lo(高/低位)算法生成主鍵,需要另外建表儲存主鍵生成的曆史狀态(這表隻需要一個列和高位初始值)。

hi/lo算法産生的辨別隻在一個特定的DB中是唯一的。所有資料庫都可用。

如果同一個資料庫裡多張表都需要用;可以建多張主鍵表,也可以共用同一字段,但最好是用同一張主鍵表的不同字段。

<id name="id" column="id">

<generator class="hilo">

<!--指定高位取值的表-->

<param name="table">high_val</param>

<!--指定高位取值的列-->

<param name="column">nextval</param>

<!--指定低位最大值,當取到最大值是會再取一個高位值再運算-->

<param name="max_lo">5</param>

</generator>

</id>

3) sequence:采用資料庫提供的Sequence機制。

Oracle,DB2等資料庫都提供序列發生器生成主鍵,Hibernate也提供支援。

<id name="id" column="id">

<generator class="sequence">

<param name="sequence">序列名</param>

</generator>

</id>

4) seqhilo:功能同hilo,隻是自動建表儲存高位值。主鍵生成的曆史狀态儲存在Sequence中。

隻能用于Oracle等支援Sequence的資料庫。

<id name="id" column="id"><generator class="hilo">

<param name="sequence">high_val_seq</param>

<param name="max_lo">5</param>

</generator></id>

5) increment:主鍵按數值順序遞增。

作用類型:long,short,int

使用場景:在沒有其他程序同時往同一張表插資料時使用,在cluster下不能使用

6) indentity:采用資料庫提供的主鍵生成機制。特點:遞增。(Oracle不支援)

通常是對DB2,Mysql, MS Sql Server, Sybase, Hypersonic SQL(HSQL)内置的辨別字段提供支援。

傳回類型:long,short, int

<id name="id" column="id"><generator class="identity"/></id>

注:使用MySql遞增序列需要在資料庫建表時對主健指定為auto_increment屬性。用Hibernate建表則不需要寫。

(oid int primary key auto_increment)

7) native:由Hibernate根據底層資料庫自行判斷采用indentity, hilo或sequence中的一種。

是最通用的實作,跨資料庫時使用。Default.sequence為hibernate_sequence

<id name="id" column="id"><generator class="native"/></id>

8) foreign:由其他表的某字段作為主鍵,通常與<one-to-one>聯合使用;共享主健(主鍵與外鍵),兩id值一樣。

<id name="id" column="id" type="integer">

<generator class="foreign">

<param name="property">car</param>

</generator>

</id>

9) UUID:

uuid.hex:由Hibernate基于128位唯一值産生算法生成十六進制數(長度為32的字元串---使用了IP位址)。

uuid.string:與uuid.hex一樣,但是生成16位未編碼的字元串,在PostgreSQL等資料庫中會出錯。

特點:全球唯一;ID是字元串。

10)select:通過DB觸發器(trigger)選擇一些唯一主鍵的行,傳回主鍵值來配置設定主鍵

11)sequence-identity:特别的序列發生政策,使用DB序列來生成值,通常與JDBC3的getGenneratedKeys一起用,使得在執行insert時就傳回生成的值。Oracle 10g(支援JDK1.4)驅動支援這一政策。

2、複合主鍵政策

步驟一:建立資料庫表,設定聯合主鍵限制

步驟二:編寫主持久化類以及主鍵類;編寫主鍵類時,必須滿足以下要求:

1)實作Serializable接口

2)覆寫equals和hashCode方法

3)屬性必須包含主鍵的所有字段

步驟三:編寫*.hbm.xml配置檔案

<composite-id name="dogId" class="composite.vo.DogId">

<key-property name="name" type="string"><column name="d_name"/></key-property>

<key-property name="nick" type="string"><column name="d_nick"/></key-property>

</composite-id>

六、 Hibernate的查詢方案(應該熟悉各種查詢的使用方法)

1、利用Session接口提供的load方法或者get方法

2、Hibernate提供的主要查詢方法

1)Criteria Query(條件查詢)的步驟:

(1)通過Session來建立條件查詢對象Criteria

Criteria criteria = session.createCriteria(Course.class);

(2)建構條件---建立查詢條件對象Criterion

Criterion criterion1 = Property.forName("id").ge(39);//通過Property來建立

Criterion criterion2 = Restrictions.le("cycle", 5); //通過Restrictions來建立

(3)查詢對象關聯條件

criteria.add(criterion1);

(4)執行條件查詢

List<Course> courses = criteria.list();

2)HQL(Hibernate Qurey Language)

特點: 文法上與SQL類似; 完全面向對象的查詢; 支援繼承、多态、關聯

(1) FROM子句

例如:查詢所有的學生執行個體

Query query=session.createQuery("from Student");

query.list();

(2) SELECT子句

選擇哪些對象和屬性傳回到結果集

A、SELECT語句後可以跟多個任意類型的屬性,傳回結果儲存在Object類型的數組中

//A、B、C、都是查詢學生的姓名和年齡

Query query=session.createQuery("select stu.name,stu.age from Student as stu");

List<Object[]> os=query.list();//傳回的Object數組中有兩個元素,第一個是姓名,第二個是年齡

B、SELECT語句後可以跟多個任意類型的屬性,傳回結果也可以儲存在List中

Query query=session.createQuery ("select new List(stu.name,stu.age) from Student as stu");

List<List> lists=query.list();

C、SELECT語句後可以跟多個任意類型的屬性,傳回結果也可以是一個類型安全的POJO對象

Query query=session.createQuery

("select new Student(stu.name,stu.age) from Student as stu");

List<Student> stuList=query.list();//注意:Student類必須有Student(String,int)的構造方法

D、SELECT子句中可以使用聚集函數、數學操作符、連接配接

支援的聚集函數:avg、sum、min、max、count ….

(3) WHERE子句,限制傳回結果集的範圍

(4) ORDER BY子句,對傳回結果集進行排序

3)Native SQL(原生SQL查詢)

可移植性差:資源層如果采用了不同的資料庫産品,需要修改代碼---非不得已,不推薦使用

步驟一:調用Session接口上的createSQLQuery(String sql)方法,傳回SQLQuery

步驟二:在SQLQuery對象上調用addEntity(Class pojoClass) //設定查詢傳回的實體

例如:

SQLQuery query =session.createSQLQuery(“select * from student limit 2,10”)

query.addEntity(Student.class);

List<Student> stuList=query.list();

七、 Hibernate對象的狀态

實體對象的三種狀态:

1) 暫态(瞬時态)(Transient)---實體在記憶體中的自由存在,它與資料庫的記錄無關。

po在DB中無記錄(無副本),po和session無關(手工管理同步)

如:

Customer customer = new Customer();

customer.setName("eric");

這裡的customer對象與資料庫中的資料沒有任何關聯

2) 持久态(Persistent)---實體對象處于Hibernate架構的管理中。

po在DB中有記錄,和session有關(session自動管理同步)

3)遊離态(脫管态)(Detached)

處于Persistent狀态的實體對象,其對應的Session執行個體關閉之後,那麼,此對象處于Detached狀态。

po在DB中有記錄,和session無關(手工管理同步)

無名态:po處于遊離态時被垃圾回收了。沒有正本,隻有DB中的副本。

po處于暫态時被垃圾回收了,則死亡。(唯一可以死亡的狀态)

實質上,這三個狀态是:持久對象的正副本與同步的關系

原則:盡量使用持久态。

三态的轉換:

暫态--->持久态

A.調用Session接口上的get()、load()方法

B.調用Session接口上的save()、saveOrUpdate()方法

持久态--->暫态

delete();

遊離态--->持久态

update()、saveOrUpdate()、lock();

(lock不建議用,危險;肯定沒變化時用,有則用updata)

持久态--->遊離态

evict()、close()、clear()

(一般用evict,隻關閉一個實體的連接配接;close關閉整個連接配接,動作太大)

八、 映射(重點掌握和了解,注意配置的細節)

關聯關系:A有可能使用B,則AB之間有關聯關系(Java裡指A有B的引用)。

雙邊關系、傳遞性、方向性、名稱、角色(權限)、數量(1:1;1:m;n:m)、關聯強度

委托:整體跟部分之間是同一類型。

代理:整體跟部分之間不是同一類型。

A. 單一實體映射:最簡單、基本映射(最重要);任何其他映射種類的基礎。

原則:

1.類->表;一個類對應一個表。

2.屬性->字段:普通屬性、Oid;一個屬性對應一個字段。

B. 實體關系映射:

a.關聯關系映射:(最難、量最多)

1.基數關系映射:

一對一(one to one) (共享主鍵、唯一外鍵)

一對多(one to many) (1:m) 作級聯,删one後連着删many

多對一(many to one) (m:1) 不作級聯,删many中一個,不删one

多對多(many to many)(n:m = 1:n + m:1)

2.元件關系映射:(一個類作為另一個類的零件,從屬于另一個類,沒有自己的XML)

單一元件關系映射

集合元件關系映射

b.繼承關系映射:(最普遍。兩個類有繼承關系,在本質上他們就是一對一關系。共享主健。)

有三種映射方案:

1.一個類一個表(效率很低;最後考慮使用,一般是資料量較大和父子類重複字段不多的時候用)

隻有當子類中的屬性過多時才考慮每個類建一個表的政策。

2.一個實體一個表(多表查詢效率低,不考慮多态時用)

不考慮多态時,最好是用隻針對具體類建表,而考慮多态時盡量使用所有類建一個表

3.所有類一個表(查詢效率最高,結構簡單;字段數不超過100個時使用,首選)

c.集合映射(值類型)

Set 不重複、無順序

List 可重複、有順序

Map

Bag 可重複、無順序(bag本身也是list實作的)

雙向關聯(Bidirectional associations)(相當于兩個單向關聯)

單向關聯(Unidirectional associations)

"一"方的配置:

<!-- 表明以Set集合來存放關聯的對象,集合的屬性名為orders;一個"customer"可以有多個"order" -->

<!-- inverse="true"表示将主要權交給order,由order對象來維護關聯關系,

也就是說order對象中的關聯屬性customer的值的改變會反映到資料庫中 -->

<set name="orders" cascade="save-update" inverse="true">

<!-- 表明資料庫的orders表通過外鍵customer_id參照customer表 -->

<key column="customer_id"/>

<!-- 指明Set集合存放的關聯對象的類型 -->

<one-to-many class="many_to_one.vo.Order"/>

</set>

"多"方的配置:

<many-to-one

name="customer"

class="many_to_one.vo.Customer"

column="customer_id"

not-null="true"

cascade="save-update"

/>

cascade屬性:設定級聯操作(插入、修改、删除)。

cascad屬性值

 描述

none

 儲存、更新或删除目前對象時,忽略其他關聯對象,預設屬性值

save-update

 通過Session的save()、update()以及saveOrUpdate()方法來保持、更新目前對象時級聯,所有關聯的建立對象,并且級聯更新所有有關聯的遊離對象

delete

 當通過Session的delete()方法來删除目前對象時,級聯删除所有關聯對象

all

 包含所有的save-update以及delete行為

delete-orphan

 删除所有和目前對象解除關聯關系的對象

all-delete-orphan

 包含all與delete-orphan的動作

inverse屬性:表示是否将目前屬性的值的變化反映到資料庫中去。

false --- 表示反映到資料庫中

true ---表示不反映到資料庫中

Set的lazy屬性:

A.不設定lazy值,預設true 現象:查詢Customer時,不會主動查詢關聯表Orders(SQL語句)

B.設定lazy=false 現象:出現查詢Orders表的SQL語句

3、多對多

預設情況下,由兩方共同維護關聯關系。也就是兩個對象關聯屬性的值的改變都會反映到資料庫中。

九、 Hibernate控制的事務

事務保證原子操作的不可分,也就是操作的同時成功或同時失敗。

hibernate的事務隔離級别和JDBC中大緻相同。

設定時要在hibernate.cfg.xml配置

<property name="hibernate.connection.isolation">4</property>

1: 讀未送出的資料(Read uncommitted isolation) 髒讀

2: 讀已送出的資料(Read committed isolation) 不可重複讀

4: 可重複讀級别(Repeatable read isolation) 幻讀

8: 可串行化級别(Serializable isolation)

hibernate的鎖(悲觀鎖,樂觀鎖)

1.悲觀鎖是由資料庫本身所實作的,會對資料庫中的資料進行鎖定,也就是鎖行。(更新期間不許其他人更改)

LockMode.UPGRADE,修改鎖,在get()方法中加上這個設定作為第三個參數。

LockMode.NONE 無鎖機制

LockMode.READ 讀取鎖

LockMode.WRITE 寫入鎖,不能在程式中直接使用

還可以使用Session.lock() Query.setLockMode() Criteria.setLockMode()方法來設定鎖,檢測版本号,一旦版本号被改動則報異常。

2.樂觀鎖,也就是通過對記錄加上某些資訊來解決并發通路的問題。(認為更新期間不會有其他更改)

版本檢查;要在其表中多加上一清單示版本資訊,會在讀取時讀到這個版本号,并在修改之後更新這個版本号;

更新瞬間加鎖,并且隻有版本号相同才會予以更新,如果版本号不同,就會抛出例外。

<version name="version" column="version" type="integer" />

本文來自CSDN部落格,轉載請标明出處:http://blog.csdn.net/elifefly/archive/2009/06/22/4290169.aspx