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();
}
}