1. 程式人生 > >Hibernate使用要點

Hibernate使用要點

Hibernate 是一個優秀的持久層的ORM(物件關係對映)框架,對JDBC進行了輕量級的封裝,由於它可以自動生成sql語句自動執行,因此可以讓我們使用物件程式設計的思想來操作資料庫,簡化了資料操作的繁雜性。

  • O: Object物件,面嚮物件語言領域,Java中的JavaBean

  • R: 關係資料庫領域的Relational(資料庫中表的結構)

  • M: 對映Mapping(XML的配置檔案)

使用Hibernate操作資料庫要配置Bean類的對映檔案和Hibernate的核心配置檔案

先來看一個Hibernate的核心配置檔案hibernate.cfg.xml

例項如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
	<session-factory>
<!-- hibernate的必配選項 -->
	<!-- 配置資料庫驅動 -->
		<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
	<!-- 配置資料庫url -->
		<property name="hibernate.connection.url">jdbc:mysql:///test</property>
	<!-- 配置資料庫使用者名稱 -->
		<property name="hibernate.connection.username">root</property>
	<!-- 配置資料密碼 -->
		<property name="hibernate.connection.password">123456</property>
	<!-- 配置資料庫方言 -->
		<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- hibernate的必配選項結束 -->
	
	
<!-- hibernate的可選配置項 -->
	<!-- 配置執行過程中的sql語句展示 -->
		<property name="hibernate.show_sql">true</property>
		
	<!-- 美化展示的sql語句 -->
		<property name="hibernate.format_sql">true</property>
		
	<!-- 使用第三方連線池 -->
		<property name="hibernate.connection.provider_class">org.hibernate.c3p0.internal.C3P0ConnectionProvider</property>
		
	<!-- 設定第三方連線池的屬性 -->
		<property name="hibernate.c3p0.max_size">20</property>
		<property name="hibernate.c3p0.min_size">5</property>
		<property name="hibernate.c3p0.timeout">5000</property>
	<!-- 配置DDL資料庫規則 -->
	<!-- 
		none:不用Hibernate自動生成表(預設)
		create-drop:每次都會建立一個新的表,執行程式結束後刪除這個表.
		create:每次都會建立一個新的表.
		update:有(表, 列)就使用, 沒有(表, 列)就建立
		validate:只會使用原有的表.對對映關係進行校驗.
	 -->
		<property name="hibernate.hbm2ddl.auto">update</property>
	<!-- 配置與本地執行緒繫結的Session物件(操作事務保證session的同一性) -->
		<property name="hibernate.current_session_context_class">thread</property>
		
	<!-- 配置對映檔案 -->
		<mapping resource="com/yanghao/bean/Actor.hbm.xml"/>
		
		<mapping resource="com/yanghao/bean/Category.hbm.xml"/>
		<mapping resource="com/yanghao/bean/Product.hbm.xml"/>
		
		<mapping resource="com/yanghao/bean/Student.hbm.xml"/>
		<mapping resource="com/yanghao/bean/Course.hbm.xml"/>
<!-- hibernate的可選配置項結束-->
	
	</session-factory>
</hibernate-configuration>

一個簡單的bean(Actor.java)的對映檔案Actor.hbm.xml:

類中的屬性:

private Integer aid;
private String name;
private String age;
private String birthday;
private String area;
Actor.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    
<hibernate-mapping>
	<class name="com.yanghao.bean.Actor" table="actor" >
		<!-- 配置主鍵 -->
		<!-- 主鍵生成策略 -->
		<!-- 
			increment:檢索自增,會先查詢表中的最大的下標,然後下標加一作為下一個新插入的資料的主鍵,在多執行緒和叢集中有很大的問題,不推薦使用
			assigned(指定的、賦值的):自定義主鍵
			identity:自動增長,有索引的增長,Mysql的自動增長策略
			sequence:自動增長,有索引的增長,Oracle的自動增長策略
			native:本地策略,根據不同資料庫能進行不同的自動增長策略的選擇,如果是mysql,就用identity,如果是Oracle就用sequence
			
			uuid:隨機的字串策略,用於生成唯一的字串主鍵的策略
		 -->
		<id name="aid" column="aid">
			<generator class="native"></generator>
		</id>
		
		<!-- 配置對應表中的屬性 -->
		<property name="name" column="name"/>
		<property name="age" column="age"/>
		<property name="birthday" column="birthday"/>
		<property name="area" column="area"/>
	</class>
</hibernate-mapping>

將一個Actor的物件對映到資料庫中,獲取一個Session物件,使用其save方法儲存到資料庫

        @Test
	public void test() {
		//使用hibernate操作資料庫的步驟
		//讀取配置檔案,載入配置預設的配置檔案
		Configuration configuration = new Configuration();
		configuration.configure();
		
		//建立SessionFactory獲取Session物件
		SessionFactory sessionFactory = configuration.buildSessionFactory();
		Session session = sessionFactory.openSession();
		
		//開啟事務
		Transaction transaction = session.beginTransaction();
		
		//執行資料庫操作
		Actor actor = new Actor();
		actor.setName("黑妞");
		actor.setAge("2");
		actor.setBirthday("20000102");
		actor.setArea("繁榮山丘");
		session.save(actor);
		
		//提交事務
		transaction.commit();
	
		//關閉資源
		session.close();
		sessionFactory.close();
	}

為了使操作方便,把獲取session物件的操作封裝到工具類中

public class HibernateUtil {
	
	private static SessionFactory sessionFactory;
	private static Configuration configuration;
	
	static {
		configuration = new Configuration();
		configuration.configure();
		sessionFactory = configuration.buildSessionFactory();
	}
	
	//私有構造方法,不能通過構造方法建立物件
	private HibernateUtil(){
	}
		
	//獲取新的Session物件
	public static Session getSession(){
		Session session = sessionFactory.openSession();
		return session;
	}
	
	//獲取當前執行緒中唯一的Session物件
	public static Session getCurrentSession(){
		return sessionFactory.getCurrentSession();
	}		
}

持久化物件(持久化物件創建出來的)在Hibernate的管理中有三種狀態:(OID就是物件的ID)

1、瞬時態---沒有標識OID,沒有納入session的管理

2、持久態--有標識的OID,納入了session的管理-------------持久態的物件內容發生變化會把資料庫中對應的記錄修改

3、託管態--有標識的OID,沒有納入session的管理

三種狀態也可以互相轉換:


關於持久化物件發生改變會自動改變資料庫的原理如下:
先做一個斷點測試
        @Test
	public void test3(){
		
		Session session = HibernateUtil.getSession();
		Transaction transaction = session.beginTransaction();
		Actor actor = new Actor();
		actor.setName("皮蛋");
		actor.setAge("3");
		actor.setBirthday("20000101");
		actor.setArea("繁榮山丘");
		session.save(actor);
		transaction.commit();
		
		Transaction transaction2 = session.beginTransaction(); //此處加了斷點,為了檢視資料的變化
		actor.setAge("6");
		actor.setName("蛋皮"); //此處加了斷點
	        //session.update(actor);//不需要更新或者儲存當前的物件就能更新資料庫裡面的值
		transaction2.commit();

		session.close();
	}

在斷點之前當我們檢視session裡面的內容時是這樣的



資料庫裡面是這樣的:


當我們執行到修改這個持久態物件的年齡和名字的時候快取區和快照區的內容發生了變化:


此時,資料庫裡面的資料也發生了更改,注意此時並沒有更新和儲存物件:


實現原理:當第一次儲存完該物件到資料庫的時候,這個物件已經納入了session的管理,物件此時是持久態的,此時Hibernate會把當前物件的狀態儲存一份到一級快取的快照區,當我們修改當前持久態物件的資料的時候,Hibernate會比對當前的快照區,如果發現數據不一致,就自動更新資料庫並重新儲存當前物件的新狀態到快照區.

前面都是操作單表的資料,就是一對一的關係,那麼如何關聯一對多、多對一、多對多和表之間的資料呢?---建立物件和表之間的對映。

一對多(分類和商品)Category.hbm.xml和Product.hbm.xml

 //分類屬性                                                                        //商品屬性
 private Integer cid;                                                               private Integer pid;
 private String cname;                                                              private String pname;
 private Set<Product> products;                                                     private String price;
                                                                                    private String number;
                                                                                    private Category category;

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    
<hibernate-mapping>
	<class name="com.yanghao.bean.Category" table="category" >
		<!-- 配置主鍵 -->
		<!-- 主鍵生成策略 -->
		<!-- 
			increment:檢索自增,會先查詢表中的最大的下標,然後下標加一作為下一個新插入的資料的主鍵,在多執行緒和叢集中有很大的問題,不推薦使用
			assigned(指定的、賦值的):自定義主鍵
			identity:自動增長,有索引的增長,Mysql的自動增長策略
			sequence:自動增長,有索引的增長,Oracle的自動增長策略
			native:本地策略,根據不同資料庫能進行不同的自動增長策略的選擇,如果是mysql,就用identity,如果是Oracle就用sequence
		
			uuid:隨機的字串策略,用於生成唯一的字串主鍵的策略
		 -->
		<id name="cid" column="cid">
			<generator class="native"></generator>
		</id>
		
		<!-- 配置對應表中的屬性 -->
		<property name="cname" column="cname"/>
		
		<!-- key的column表示多的一方的外來鍵名,inverse=true讓一方級聯儲存多方時多方放棄外來鍵維護,因為外來鍵是屬於多的一方的,兩方都維護外來鍵會產生重複的sql操作-->
		<set name="products" cascade="delete" inverse="true">
			<key column="cid"/>
			<one-to-many class="com.yanghao.bean.Product"/>		
		</set>
	</class>
</hibernate-mapping>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    
<hibernate-mapping>
	<class name="com.yanghao.bean.Product" table="product" >
		<!-- 配置主鍵 -->
		<!-- 主鍵生成策略 -->
		<!-- 
			increment:檢索自增,會先查詢表中的最大的下標,然後下標加一作為下一個新插入的資料的主鍵,在多執行緒和叢集中有很大的問題,不推薦使用
			assigned(指定的、賦值的):自定義主鍵
			identity:自動增長,有索引的增長,Mysql的自動增長策略
			sequence:自動增長,有索引的增長,Oracle的自動增長策略
			native:本地策略,根據不同資料庫能進行不同的自動增長策略的選擇,如果是mysql,就用identity,如果是Oracle就用sequence
			
			uuid:隨機的字串策略,用於生成唯一的字串主鍵的策略
		 -->
		<id name="pid" column="pid">
			<generator class="native"></generator>
		</id>
		
		<!-- 配置對應表中的屬性 -->
		<property name="pname" column="pname"/>
		<property name="price" column="price"/>
		<property name="number" column="number"/>
		
		
		<many-to-one name="category" class="com.yanghao.bean.Category" column="cid" cascade="save-update"/>
	</class>
</hibernate-mapping>

多對多(學生和選課)Student.hbm.xml和Course.hbm.xml

//學生類屬性                                                                     //課程屬性
private Integer sid;                                                            private Integer cid;
private String sname;                                                           private String cname;
	
private Set<Course> courses = new HashSet<Course>();                            private Set<Student> students = new HashSet<Student>();

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    
<hibernate-mapping>
	<class name="com.yanghao.bean.Student" table="student" >
		<!-- 配置主鍵 -->
		<!-- 主鍵生成策略 -->
		<!-- 
			increment:檢索自增,會先查詢表中的最大的下標,然後下標加一作為下一個新插入的資料的主鍵,在多執行緒和叢集中有很大的問題,不推薦使用
			assigned(指定的、賦值的):自定義主鍵
			identity:自動增長,有索引的增長,Mysql的自動增長策略
			sequence:自動增長,有索引的增長,Oracle的自動增長策略
			native:本地策略,根據不同資料庫能進行不同的自動增長策略的選擇,如果是mysql,就用identity,如果是Oracle就用sequence
			
			uuid:隨機的字串策略,用於生成唯一的字串主鍵的策略
		 -->
		<id name="sid" column="sid">
			<generator class="native"></generator>
		</id>
		
		<!-- 配置對應表中的屬性 -->
		<property name="sname" column="sname"/>
		
		<set name="courses" table="s_c_table">
			<key column="sid"/>
			<many-to-many column="cid" class="com.yanghao.bean.Course"/>
		</set>
	</class>
</hibernate-mapping>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    
<hibernate-mapping>
	<class name="com.yanghao.bean.Course" table="course" >
		<!-- 配置主鍵 -->
		<!-- 主鍵生成策略 -->
		<!-- 
			increment:檢索自增,會先查詢表中的最大的下標,然後下標加一作為下一個新插入的資料的主鍵,在多執行緒和叢集中有很大的問題,不推薦使用
			assigned(指定的、賦值的):自定義主鍵
			identity:自動增長,有索引的增長,Mysql的自動增長策略
			sequence:自動增長,有索引的增長,Oracle的自動增長策略
			native:本地策略,根據不同資料庫能進行不同的自動增長策略的選擇,如果是mysql,就用identity,如果是Oracle就用sequence
			
			uuid:隨機的字串策略,用於生成唯一的字串主鍵的策略
		 -->
		<id name="cid" column="cid">
			<generator class="native"></generator>
		</id>
		
		<!-- 配置對應表中的屬性 -->
		<property name="cname" column="cname"/>
		
		<!-- 雙向關聯,讓一方放棄外來鍵的維護,否則雙方生成中間表會產生一樣的sql語句,導致主鍵衝突 -->
		<set name="students" table="s_c_table" cascade="save-update" inverse="true">
			<key column="cid"></key><!-- 外來鍵名 -->
			<many-to-many column="sid" class="com.yanghao.bean.Student"/>
		</set>
	</class>
</hibernate-mapping>

Hibernate的查詢方式彙總:

OID檢索 (get  load  save  update  delete)

    get方法和load方法的區別

    get方法的特點

​ get方法採用的是立即檢索策略(查詢):執行到這行的時候,馬上傳送SQL查詢

​ get方法查詢後返回的是真實物件的本身

load方法的特點

​ load方法採用的是延遲載入(懶載入lazy:什麼時候使用,才會去載入)的策略:執行到這行的時候,不會發送 SQL語句,什麼時候使用這個物件,才會傳送SQL語句。

​ load查詢後返回的是代理物件

物件導航檢索(通過一個物件獲得其關聯物件

例如:

Category category = session.get(Category.class, 1);
Set<Product> products =   category.getProducts();

HQL檢索 (Hibernate查詢語言,與SQL類似,hql是面向物件的 )

語法: String hql =...

Query query = session.createQuery(hql);

  • list(); 查詢多個

  • uniqueResult();查詢一個

    原則: 把表名改成類名, 把資料庫的列改成Java裡面的屬性

QBC,Query By Criteria(條件查詢,更加面向物件的查詢方式)

語法:

//建立QBC條件查詢
Criteria criteria = session.createCriteria(Class);
//新增條件
criteria.add(Restrictions.api...);
//查詢多個
List list = criteria.list();
//或者查詢一個
Object object =  criteria.uniqueResult();
條件(Restriction 限定和限制)
運算子條件API描述
=Restrictions.eq()等於
>Restrictions.gt()大於
<Restrictions.lt()小於
>=Restrictions.ge()大於等於
<=Restrictions.le()小於等於
betweenRestrictions.between()在某個範圍內
likeRestrictions.like()模糊查詢
inRestrictions.in()在...中
andRestrictions.and()並且






相關推薦

hibernate要點(轉載)

hibernate要點1.兩種配置檔案:   A.hibernate.cfg.xml   和   B.hibernate.properties   A中可含對映檔案的配置,而B中hard codes加對映檔案。  A。Configuration config=new Conf

Hibernate【緩存】知識要點

常用 以及 provide 懶加載 更改 pub 語句 com 效率 對象狀態 Hibernate中對象的狀態: 臨時/瞬時狀態 持久化狀態 遊離狀態 學習Hibernate的對象狀態是為了更清晰地知道Hibernate的設計思想,以及是一級緩存的基礎...當然啦,也就

Hibernate使用要點

Hibernate 是一個優秀的持久層的ORM(物件關係對映)框架,對JDBC進行了輕量級的封裝,由於它可以自動生成sql語句自動執行,因此可以讓我們使用物件程式設計的思想來操作資料庫,簡化了資料操作的繁雜性。O: Object物件,面嚮物件語言領域,Java中的JavaBe

Hibernate面試要點

get和load的區別: 1>不存在對應記錄時表現不一樣 2>load返回的是代理物件(javassist.jar生成二進位制碼),等到真正用到物件的內容才會發出SQL語句 3>get直接從資料庫載入,不會延遲 無論是get還是load,都會首先查詢快取

hibernate學習要點指引

最近幾天,團隊有幾個人在blog上開始貼自己學習hibernate的一些程式碼和心得了。昨天幫他們除錯程式碼的時候,才對他們最近的學習過程有一個瞭解。回想兩年多前,自己開始hibernate學習的過程,貼點東西在這裡。 不懂技術的人或者技術新手往往容易被“框架”二字所唬住,

Hibernate開發要點

1.兩種配置檔案:   A.hibernate.cfg.xml   和   B.hibernate.properties   A中可含對映檔案的配置,而B中hard codes加對映檔案。   A。Configuration config=new Configurati

Hibernate效能優化要點

1.儘量使用many-to-one,避免使用單項one-to-many 2.靈活使用單向one-to-many 3.不用一對一,使用多對一代替一對一 4.配置物件快取,不使用集合快取 5.一對多使用Bag 多對一使用Set 6.繼承使用顯示多型  HQL:from object  polymorphism="

淺談Hibernate效能優化要點

1.儘量使用many-to-one,避免使用單項one-to-many 2.靈活使用單向one-to-many 3.不用一對一,使用多對一代替一對一 4.配置物件快取,不使用集合快取 5.一對多使用Bag 多對一使用Set 6.繼承使用顯示多型 HQL:from object polymorphism="ex

Hibernate學習要點

關於認識Hibernate主要從用法和原理2方面進行。 1.用法 關於SessionFactory配置 O/R mapping 配置 --基本/集合/元件/繼承 操作持久資料 --增刪改 --誇session的儲存 --查詢 --session其他操作 關於其他 --鎖

hibernate

可能 port src query rac session join() osi function package com.tudou.hibernates.t1; import java.util.List; import org.hibernate

Struts2+Hibernate框架探險

service 分支 環境 eclips 操作 factory rds 相對 targe 寫這篇文章的目的 了解 JavaWeb 開發的人都知道SSH和SSM框架,前段時間開始接觸 JavaWeb 開發,看了幾個教學視頻後就想上手構建一個小型 Web項目,可在跟著視頻敲代碼

高級系統架構師培訓要點:減少資源消耗,靠虛擬代理方案解決了!

解決方案 虛擬代理 應用程序 系統性能和吞吐量的需求決定了單純在數據庫中操作整個倉庫拓撲數據是不現實的。這種大量的服務器端對象,會消耗大量的服務器內存和活動對象表的空間,如果這些對象使用得比較少,就很容易造成數據庫服務端資源的浪費。把倉庫拓撲數據存放在本地內存中,形成內存數據對象(數據緩存),以便

Hibernate之三態篇

結果 定義 tro 緩存 session nsa weight sys -c 一、概況 (一)瞬時狀態(暫時態) 在對象中假設對象剛被創建但沒有被持久化的話就是瞬時態 特點: (1) 不和 Session 實例關聯 (2)

29個要點幫你更好的完成java代碼優化

範圍 常見 string類 += 用戶 帶來 指令 有用 訪問 在Java程序中,性能問題的大部分原因並不在於Java語言,而是在於程序本身。養成好的代碼編寫習慣非常重要,比如正確地、巧妙地運用java.lang.String類和java.util.Vector類,它能夠顯

【java】itoo項目實戰之hibernate 懶載入優化性能

bsp xtra extra pda 程序 前端框架 外連接 獲取 轉換成 在做itoo 3.0 的時候,考評系統想要上線,就開始導入數據了,僅僅導入學生2萬條數據,可是導入的速度特別的慢。這個慢的原因是由於導入的時候進行了過多的IO操作。可是導入成功之後,

Spring(三):Spring整合Hibernate

ng- checkout wait 哪些 check driver eas package class 背景:   本文主要介紹使用spring-framework-4.3.8.RELEASE與hibernate-release-5.2.9.Final項目整合搭建

基於Struts2+Hibernate的DetachedCriteria多條件查詢

img 類別 ota 配置 his property mat total ide 上一篇我們講訴了基於SSH框架利用Criteria的多條件查詢,這一篇我們就接著來看基於SSH框架利用DetachedCriteria的多條件查詢。 一、Jsp表單查詢頁 1 &

Hibernate 入門小案例

java程序 div nocache org student 包含 target .so tell 前言: 學習學到現在終於要學習框架了,心裏有點小激動呢,也不知道自己能不能學好呢,只能按著一步一個腳印的走下去,好了廢話不多說。讓我們打開hibernate

[.NET] 《Effective C#》快速筆記 - C# 高效編程要點補充

擔心 cti 四十六 catch con 影響 ted 註冊 ref 《Effective C#》快速筆記 - C# 高效編程要點補充 目錄 四十五、盡量減少裝箱拆箱 四十六、為應用程序創建專門的異常類 四十七、使用強異常安全保證 四十八、盡量使用安全的

Spring(五):Spring&Struts2&Hibernate整合後,實現查詢Employee信息

view event last .html ssh tla url 配置文件 hid 背景:   基於之前兩篇文章《Spring(三):Spring整合Hibernate》、《Spring(四):Spring整合Hibernate,之後整合Struts2》,了解了