1. 程式人生 > >hibernate教程--常用配置和核心API詳解

hibernate教程--常用配置和核心API詳解

一、Hibernate的常用的配置及核心API.

1.1 Hibernate的常見配置:

1.1.1、核心配置:

核心配置有兩種方式進行配置:

 1)屬性檔案的配置:

* hibernate.properties

* 格式:

* key=value

 hibernate.connection.driver_class=com.mysql.jdbc.Driver

 注意:沒有辦法在核心配置檔案中載入對映檔案.(必須手動編碼的方式進行載入.)

2)XML格式檔案配置:

* hibernate.cfg.xml

* 格式:

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

3)核心配置中:

1.必須的配置:

* 連線資料庫4個基本引數:

hibernate.connection.driver_class  連線資料庫驅動程式

hibernate.connection.url   連線資料庫URL

hibernate.connection.username  資料庫使用者名稱

hibernate.connection.password   資料庫密碼

* Hibernate的方言:

hibernate.dialect   操作資料庫方言

2.可選的配置:

hibernate.show_sql  true 在控制檯上輸出SQL語句

hibernate.format_sql  true  格式化控制檯輸出的SQL語句

hibernate.connection.autocommit  true 事務是否自動提交

hibernate.hbm2ddl.autocreate/create-drop/update/validate

* create:每次執行的時候,建立一個新的表.(如果以前有該表,將該表刪除重新建立.) 一般測試的時候的使用.

* create-drop:每次執行的時候,建立一個新的表,程式執行結束後將這個表,刪除掉了.一般測試的時候使用.

* update:如果資料庫中沒有表,建立一個新的表,如果有了,直接使用這個表.可以更新表的結構.

* validate:會使用原有的表.完成校驗.校驗對映檔案與表中配置的欄位是否一致.不一致報錯.

3.對映的配置:

* 在核心配置檔案中載入對映檔案:

 <mapping resource="cn/itcast/hibernate3/demo1/Customer.hbm.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>
	<!-- 必須去配置的屬性 -->
	<!-- 配置資料庫連線的基本資訊: -->
	<property name="hibernate.connection.driver_class">
		com.mysql.jdbc.Driver
	</property>
	<property name="hibernate.connection.url">
		jdbc:mysql:///hibernate3_test
	</property>
	<property name="hibernate.connection.username">root</property>
	<property name="hibernate.connection.password">123</property>
	<!-- Hibernate的方言 -->
	<!-- 生成底層SQL不同的 -->
	<property name="hibernate.dialect">
		org.hibernate.dialect.MySQLDialect
	</property>

	<!-- 可選的屬性 -->
	<!-- 顯示SQL -->
	<property name="hibernate.show_sql">true</property>
	<!-- 格式化SQL -->
	<property name="hibernate.format_sql">true</property>
	
	<property name="hibernate.connection.autocommit">false</property>
	<!-- hbm:對映 to DDL: create drop alter -->
	<property name="hibernate.hbm2ddl.auto">update</property>

	<!-- C3P0連線池設定-->
	<!-- 使用c3po連線池  配置連線池提供的供應商-->
	<property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider                                                                                                                                                     </property>
	
	<!--在連線池中可用的資料庫連線的最少數目 -->
	<property name="c3p0.min_size">5</property>
	<!--在連線池中所有資料庫連線的最大數目  -->
	<property name="c3p0.max_size">20</property>
	<!--設定資料庫連線的過期時間,以秒為單位,
	如果連線池中的某個資料庫連線處於空閒狀態的時間超過了timeout時間,就會從連線池中清除 -->
	<property name="c3p0.timeout">120</property>
	 <!--每3000秒檢查所有連線池中的空閒連線 以秒為單位-->
	<property name="c3p0.idle_test_period">3000</property>

	<!-- 通知Hibernate載入那些對映檔案 -->
	<mapping resource="com/sihai/hibernate3/demo1/Customer.hbm.xml" />

</session-factory>
</hibernate-configuration>


1.1.2、對映檔案的配置:

ORM:物件和關係對映.

* 配置Java物件與表對映.

* 配置類與表的對映:

* name:類的全路徑:

* table:表的名稱:(可以省略的.使用類的名稱作為表名.)

<class name="com.sihai.hibernate3.demo1.Order" table=”orders”>

 配置普通屬性與欄位對映:

<property name="name" column="name" type="string" length=”20”/>

type:三種寫法

* Java型別:java.lang.String

* Hibernate型別:string

* SQL型別:不能直接使用type屬性,需要子標籤<column>

* <column name="name" sql-type="varchar(20)"/>

配置唯一標識與主鍵對映:

* 一個表中只有一個主鍵的形式:

<id name=”id” column=”id”>

* 生成策略:

* 一個表對應多個主鍵形式:(複合主鍵:)---瞭解.

* <composite-id></composite-id>

* 關聯關係:

* 命名SQL:

<query name="findAll">

from Customer

</query>

<sql-query name="sqlFindAll">

select * from customer

</sql-query>

<?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 :類的全路徑  table:表名稱 -->
	<class name="com.sihai.hibernate3.demo1.Customer" table="customer">
		<!-- 建立類中屬性與表中的欄位對映 -->
		<!-- 唯一標識 -->
		<!-- 使用id的標籤 配置唯一屬性 -->
		<!-- 在<id>標籤中配置一個主鍵的生成策略. -->
		<id name="id" column="id">
			<generator class="assigned"/>
		</id>
		
		<!-- 普通屬性 -->
		<!-- property標籤:對映類中的普通屬性 name:類中的屬性名稱, column:表中欄位名稱 -->
		<!-- 
			type:三種寫法
				* Java型別		:java.lang.String
				* Hibernate型別	:string
				* SQL型別		:不能直接使用type屬性,需要子標籤<column>
					* <column name="name" sql-type="varchar(20)"/>
		 -->
		<property name="name" column="name" type="string" length="20"/>
		<property name="age" column="age"/>
		
		
	</class>
	

</hibernate-mapping>


二、 Hibernate的核心API:

2.1 Hibernate的核心API:

Configuration:負責管理 Hibernate 的配置資訊

2.1.1.載入核心配置檔案:

核心配置有兩種:

* hibernate.properties:

* 載入:

* Configuration configuration = new Configuration();

* hibernate.cfg.xml:

* 載入:

* Configuration configuration = new Configuration().configure();

2.1.2.載入對映檔案:

* 第一種寫法:

* configuration.addResource("cn/itcast/hibernate3/demo1/Customer.hbm.xml");

* 第二種寫法:(要求:對映檔名稱要規範,類與對映在同一個包下)

* configuration.addClass(Customer.class);

SessionFactory:Session工廠.

Configuration物件根據當前的配置資訊生成 SessionFactory物件

SessionFactory 物件中儲存了當前的資料庫配置資訊和所有對映關係以及預定義的SQL語句

SessionFactory 物件是執行緒安全的

SessionFactory還負責維護Hibernate的二級快取

SessionFactory物件根據資料庫資訊,維護連線池,建立Session(相當於Connection)物件.

抽取工具類:

public class HibernateUtils {

private static Configuration configuration;

private static SessionFactory sessionFactory;

static{

configuration = new Configuration().configure();

sessionFactory = configuration.buildSessionFactory();

}

public static Session openSession(){

return sessionFactory.openSession();

}

public static void main(String[] args) {

openSession();

}

}


2.2.3在Hibernate中使用c3p0連線池:

* 引入c3p0的jar包

* 在核心配置中新增一段配置:

<!-- C3P0連線池設定-->

<!-- 使用c3po連線池  配置連線池提供的供應商-->

<property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider                                                                                                                                        </property>

<!--在連線池中可用的資料庫連線的最少數目 -->

<property name="c3p0.min_size">5</property>

<!--在連線池中所有資料庫連線的最大數目  -->

<property name="c3p0.max_size">20</property>

<!--設定資料庫連線的過期時間,以秒為單位,

如果連線池中的某個資料庫連線處於空閒狀態的時間超過了timeout時間,就會從連線池中清除 -->

<property name="c3p0.timeout">120</property>

 <!--每3000秒檢查所有連線池中的空閒連線 以秒為單位-->

<property name="c3p0.idle_test_period">3000</property>


2.2.4、Session:

相當於 JDBC的 Connection

Session 是應用程式與資料庫之間互動操作的一個單執行緒物件,是 Hibernate 運作的中心

Session是執行緒不安全的

所有持久化物件必須在 session 的管理下才可以進行持久化操作

Session 物件有一個一級快取,顯式執行 flush 之前,所有的持久化操作的資料都快取在 session 物件處

持久化類與 Session 關聯起來後就具有了持久化的能力

Session維護了Hiberante一級快取.

save()/persist():新增.

update() :修改

saveOrUpdate() :增加和修改物件

delete()  :刪除物件

get()/load()  :根據主鍵查詢

createQuery() :建立一個Query介面,編寫HQL語句

createSQLQuery() :建立一個SQLQuery介面,編寫SQL語句資料庫操作物件

createCriteria()  :返回一個Criteria介面.條件查詢

2.2.5、Transaction:

獲得:

Transaction tx = session.beginTransaction();

常用方法:

commit():提交相關聯的session例項

rollback():撤銷事務操作

wasCommitted():檢查事務是否提交

如果沒有開啟事務,那麼每個Session的操作,都相當於一個獨立的事務

2.2.6、Query

Query代表面向物件的一個Hibernate查詢操作

session.createQuery 接受一個HQL語句

HQL是Hibernate Query Language縮寫, 語法很像SQL語法,但是完全面向物件的

2.2.7、Criteria

Criteria條件查詢:

package com.sihai.hibernate3.demo1;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Restrictions;
import org.junit.Test;

/**
 * Hibernate入門案例的測試:
 * @author sihai
 *
 */
public class HibernateTest1 {
	
	@Test
	// 查詢所有記錄:SQL
	public void demo7(){
		// 1.載入核心配置檔案
		Configuration configuration = new Configuration().configure();
		// 2.構建Session工廠
		SessionFactory sessionFactory = configuration.buildSessionFactory();
		// 3.通過工廠建立Session
		Session session = sessionFactory.openSession();
		// 4.開啟事務
		Transaction tx = session.beginTransaction();
		
		// 5.操作
		// 查詢所有:SQL
		/*SQLQuery query = session.createSQLQuery("select * from customer");
		List<Object[]> list = query.list();
		
		for (Object[] objs : list) {
			System.out.println(Arrays.toString(objs));
		}*/
		SQLQuery query = session.createSQLQuery("select * from customer");
		query.addEntity(Customer.class);
		List<Customer> list = query.list();
		for (Customer customer : list) {
			System.out.println(customer);
		}
		
		// 6.事務提交
		tx.commit();
		// 7.釋放資源
		session.close();
		sessionFactory.close();
		
	}
	
	@Test
	// 查詢所有:QBC
	public void demo6(){
		// 1.載入核心配置檔案
		Configuration configuration = new Configuration().configure();
		// 2.構建Session工廠
		SessionFactory sessionFactory = configuration.buildSessionFactory();
		// 3.通過工廠建立Session
		Session session = sessionFactory.openSession();
		// 4.開啟事務
		Transaction tx = session.beginTransaction();
		
		// 5.操作:
		// 查詢所有 :QBC.
		/*Criteria criteria = session.createCriteria(Customer.class);
		List<Customer> list = criteria.list();*/
		Criteria criteria = session.createCriteria(Customer.class);
		criteria.add(Restrictions.eq("name", "sihai"));
		List<Customer> list = criteria.list();
		
		for (Customer customer : list) {
			System.out.println(customer);
		}
		
		// 6.事務提交
		tx.commit();
		// 7.釋放資源
		session.close();
		sessionFactory.close();
	}
	
	@Test
	// 查詢所有:HQL.
	// HQL:Hibernate Query Language.Hibernate查詢語言.面向物件的查詢.
	public void demo5(){
		// 1.載入核心配置檔案
		Configuration configuration = new Configuration().configure();
		// 手動編碼載入對映檔案:
		// configuration.addResource("com/sihai/hibernate3/demo1/Customer.hbm.xml");
		// configuration.addClass(Customer.class);
		// 2.構建Session工廠
		SessionFactory sessionFactory = configuration.buildSessionFactory();
		// 3.通過工廠建立Session
		Session session = sessionFactory.openSession();
		// 4.開啟事務
		Transaction tx = session.beginTransaction();	
		
		// 5.操作
		// 1.查詢所有的客戶
		/*Query query = session.createQuery("from Customer");
		List<Customer> list = query.list();*/
		// 2.按名稱查詢
		/*Query query = session.createQuery("from Customer where name = ?");
		query.setParameter(0, "sihai");*/
		Query query = session.createQuery("from Customer where name = :aaa");
		query.setParameter("aaa", "sihai");
		List<Customer> list = query.list();
		
		for (Customer customer : list) {
			System.out.println(customer);
		}
		
		// 6.事務提交
		tx.commit();
		// 7.釋放資源
		session.close();
		sessionFactory.close();
	}
	
	@Test
	// 刪除記錄
	public void demo4(){
		// 1.載入核心配置檔案
		Configuration configuration = new Configuration().configure();
		// 2.構建Session工廠
		SessionFactory sessionFactory = configuration.buildSessionFactory();
		// 3.通過工廠建立Session
		Session session = sessionFactory.openSession();
		// 4.開啟事務
		Transaction tx = session.beginTransaction();	
		
		// 5.操作
		// 刪除記錄有兩種方式:
		// 5.1手動建立物件的方式
		/*Customer customer = new Customer();
		customer.setId(2);
		
		session.delete(customer);*/
		
		// 5.2先查詢在刪除的方式
		Customer customer = (Customer)session.get(Customer.class, 1);
		session.delete(customer);
		
		// 6.事務提交
		tx.commit();
		// 7.釋放資源
		session.close();
		sessionFactory.close();
	}
	
	@Test
	// 修改記錄
	public void demo3(){
		// 1.載入核心配置檔案
		Configuration configuration = new Configuration().configure();
		// 2.構建Session工廠
		SessionFactory sessionFactory = configuration.buildSessionFactory();
		// 3.通過工廠建立Session
		Session session = sessionFactory.openSession();
		// 4.開啟事務
		Transaction tx = session.beginTransaction();	
		
		// 5.操作:
		// 修改記錄:兩種方式可以進行修改.
		// 5.1手動建立物件的方式
		/*Customer customer = new Customer();
		customer.setId(2);
		customer.setName("sihai");
		
		session.update(customer);*/
		
		// 5.2先查詢在修改的方式
		Customer customer = (Customer) session.get(Customer.class, 1);
		customer.setName("sihai");
		
		session.update(customer);
		
		// 6.事務提交
		tx.commit();
		// 7.釋放資源
		session.close();
		sessionFactory.close();
	}
	
	@Test
	// 按id進行查詢
	// get和load方法區別
	public void demo2(){
		// 1.載入核心配置檔案
		Configuration configuration = new Configuration().configure();
		// 2.構建Session工廠
		SessionFactory sessionFactory = configuration.buildSessionFactory();
		// 3.通過工廠建立Session
		Session session = sessionFactory.openSession();
		// 4.開啟事務
		Transaction tx = session.beginTransaction();
		// 5.操作
		// 根據id進行查詢:
		// get方法進行查詢
		Customer customer = (Customer) session.get(Customer.class, 100); // 馬上發生一條SQL進行查詢
		
		System.out.println(customer);
		
		// load方法進行查詢
		//Customer customer = (Customer) session.load(Customer.class, 100); // 沒有傳送SQL
		
		//System.out.println(customer);// 傳送SQL.
		
		// 6.事務提交
		tx.commit();
		// 7.釋放資源
		session.close();
		sessionFactory.close();
		
	}
	
	@Test
	// 儲存記錄
	public void demo1(){
		// 1.Hiberante框架載入核心配置檔案(有資料庫連線資訊)
		Configuration configuration = new Configuration().configure();
		// 2.建立一個SessionFactory.(獲得Session--相當連線物件)
		SessionFactory sessionFactory = configuration.buildSessionFactory();
		// 3.獲得Session物件.
		Session session = sessionFactory.openSession();
		// 4.預設的情況下,事務是不自動提交.
		Transaction tx = session.beginTransaction();
		// 5.業務邏輯操作
		
		// 向資料庫中插入一條記錄:
		Customer customer = new Customer();
		customer.setName("sihai");
		customer.setAge(38);
		
		session.save(customer);
		
		// 6.事務提交
		tx.commit();
		// 7.釋放資源
		session.close();
		sessionFactory.close();
	}
}


三、 Hibernate中的持久化類:

持久化類:實體類 + 對映檔案.

3.1、持久化類是有編寫規範:

1、提供一個無引數 public訪問控制符的構造器:用到反射.

2、提供一個標識屬性,對映資料表主鍵欄位:

3、java區分兩個物件是否是同一個使用 地址.

4、 資料庫區分兩條記錄是否一致:使用  主鍵.

5、 Hibernate中區分持久化物件是否是同一個,根據唯一標識:

6、 所有屬性提供public訪問控制符的 set  get 方法:框架中存值和取值的時候使用.

7、 標識屬性應儘量使用基本資料型別的包裝型別

8、 持久化類儘量不要使用final進行修飾:

 用final修飾的類是不能被繼承.無法生成代理物件.(延遲載入的時候返回代理物件.延遲載入就失效.)

9、 儘量要Hibernate自己去維護主鍵:

 3.2、主鍵的生成策略:

1、 increment:自動增長.適合 short int long...不是使用資料庫的自動增長機制.使用Hibernate框架提供的自動增長方式.

2、 select max(id) from 表; 在最大值的基礎上+1.(多執行緒的問題.)在叢集下不要使用

3、identity:自動增長.適合 short int long...採用資料庫的自動增長機制.不適合於Oracle資料庫.

4、 sequence:序列.適用於 short int long ... 應用在Oracle上 .

5、 uuid:適用於字串型別的主鍵.採用隨機的字串作為主鍵.

6、 native:本地策略.底層資料庫不同.自動選擇適用identity 還是 sequence.

7、 assigned:Hibernate框架不維護主鍵,主鍵由程式自動生成.

8、 foreign:主鍵的外來的.(應用在多表一對一的關係.)

package com.sihai.hibernate3.demo1;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import com.sihai.utils.HibernateUtils;

/**
 * 主鍵生成策略
 * @author sihai
 *
 */
public class HibernateTest3 {
	
	@Test
	// 演示increment的問題:
	public void demo1(){
		Session session = HibernateUtils.openSession();
		Transaction tx = session.beginTransaction();
		
		Customer customer = new Customer();
		customer.setName("芙蓉");
		customer.setAge(26);
		
		session.save(customer);
		
		tx.commit();
		session.close();
	}
	
	@Test
	// 演示increment的問題:
	public void demo2(){
		Session session = HibernateUtils.openSession();
		Transaction tx = session.beginTransaction();
		
		Customer customer = new Customer();
		// customer.setId(100);
		customer.setName("sihai");
		customer.setAge(26);
		
		session.save(customer);
		
		tx.commit();
		session.close();
	}
}