Hibernate核心API
一、Configuration:Hibernate配置對象
Configuration 類的作用是對Hibernate 進行配置,以及對它進行啓動。在Hibernate
的啓動過程中,
Configuration
類的實例首先定位映射文檔的位置,讀取這些配置,然後創建一個SessionFactory對象。雖然Configuration
類在整個Hibernate 項目中只扮演着一個很小的角色,但它是啓動hibernate 時所遇到的第一個對象
1、作用:加載核心配置文件
如果加載的是:hibernate.properties
Configuration cfg = new Configuration ();
//手動加載映射
cfg.addResource("com/itzheng/hibernate/demo01/Customer.hbm.xml");
如果加載的是:hibernate.cfg.xml
Configuration cfg = new Configuration ().configuer();
在hibernate.cfg.xml當中
沒有設置mapping的時候
//手動加載映射
configuration.addResource("com/itzheng/hibernate/demo01/Customer.hbm.xml");
二、SessionFactory:session工廠
SessionFactory接口負責初始化Hibernate。它充當數據存儲源的代理,並負責創建Session對象。這裏用到了工廠模式。需要注意的是SessionFactory並不是輕量級的,因爲一般情況下,一個項目通常只需要一個SessionFactory就夠,當需要操作多個數據庫時,可以爲每個數據庫指定一個SessionFactory。
SessionFactory內部維護了hibernate的鏈接池和hibernate的二級緩存(二級緩存用的不多已被替代)線程安全的對象,一個項目只需要創建一個
1、配置鏈接池(瞭解 後面交給Spring)
默認已經配好了也可以手動配置
手動配置如下
在覈心配置文件當中hibernate.cfg.xml
<!-- 配置C3P0連接池 -->
<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>
然後引入
c3po的jar,hibernate自帶
測試相關代碼可以在控制檯看到c3po相關的配置
2、抽取工具類
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
/*
* Hibernate的工具類
*/
public class HibernateUtils {
public static final Configuration cfg;
public static final SessionFactory sf;
static {
cfg = new Configuration().configure();
sf = cfg.buildSessionFactory();
}
public static Session openSession() {
return sf.openSession();
}
}
測試工具類
Transaction(數據庫事務)
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.itzheng.hibernate.demo01.Customer;
import com.itzheng.hibernate.utils.HibernateUtils;
/*
* Hibernate工具類的一個測試
*/
public class HibernateDemo02 {
@Test
// 保存客戶
public void demo01() {
//獲取到數據庫的鏈接
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();//創建數據庫事務對象開啓事務
Customer customer = new Customer();//自定義與數據庫匹配的類
customer.setCust_name("王小東");
session.save(customer);
tx.commit();//提交事務
session.close();
}
@Test
// 查詢:
public void demo02() {
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();// 創建數據庫事務對象開啓事務
// 使用get方法來進行查詢
/*
* Customer customer = session.get(Customer.class, 1l);
* System.out.println(customer);
* System.out.println("===========================");
*/
// 使用load方法查詢
Customer customer = session.load(Customer.class, 1l);//發送SQL語句
System.out.println(customer);
tx.commit();// 提交事務
session.close();
}
}
三、Session:類似Connection對象是鏈接對象(實現Hibbernate和數據庫建立連接)
Session接口負責執行被持久化對象的CRUD操作(CRUD的任務是完成與數據庫的交流,包含了很多常見的SQL語句)。
但需要注意的是Session對象是非線程安全的。同時,Hibernate的session不同於JSP應用中的HttpSession。這裏當使用session這個術語時,其實指的是Hibernate中的session,而以後會將HttpSession對象稱爲用戶session。
Session代表的是Hibernate與數據庫的鏈接對象。不是線程安全 (Session對象不可以定義爲全局變量)使用該對象的時候必須爲局部變量
Session是與數據庫交互的一個橋樑
1、Session的API
可以到Hibernate的API文檔當中找到關於Session的介紹
A、保存方法:
Serializable save(Object obj);
Serializable id = session.save(customer);
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.itzheng.hibernate.demo01.Customer;
import com.itzheng.hibernate.utils.HibernateUtils;
/*
* Hibernate工具類的一個測試
*/
public class HibernateDemo02 {
@Test
// 保存客戶
public void demo01() {
//獲取到數據庫的鏈接
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();//創建數據庫事務對象開啓事務
Customer customer = new Customer();//自定義與數據庫匹配的類
customer.setCust_name("王小東");
session.save(customer);
tx.commit();//提交事務
session.close();
}
}
B、查詢的方法:
T get(Class c,Serializable id);
T load(Class c,Serializable id);
測試代碼:
使用get方法來查詢
使用load方法來查詢
—》get方法和load方法的區別?使用Debug分別測試get方法和load方法
get方法
採用的是立即加載,執行到這行代碼的時候,就會馬上發送SQL語句去查詢
查詢後返回的是真實對象本身
查詢一個找不到的對象的時候會返回null
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.itzheng.hibernate.demo01.Customer;
import com.itzheng.hibernate.utils.HibernateUtils;
/*
* Hibernate工具類的一個測試
*/
public class HibernateDemo02 {
@Test
// 查詢:
public void demo02() {
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();// 創建數據庫事務對象開啓事務
// 使用get方法來進行查詢
Customer customer = session.get(Customer.class, 1l);
System.out.println(customer);
System.out.println("===========================");
tx.commit();// 提交事務
session.close();
}
}
load方法
採用的是延遲加載(lazy懶加載),執行到這行代碼的時候不會發送SQL語句,當真正使用該對象的時候纔會發送SQL語句
獲取其id的時候也不會發送SQL語句,但是獲取其他屬性的時候就會發生SQL語句
load方法查詢後返回的是 代理對象。
使用的是這個包產生的代理,利用javassist技術產生的代理。
查詢一個找不到的對象的時候會返回對象找不到的異常(ObjectNotFoundException)
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.itzheng.hibernate.demo01.Customer;
import com.itzheng.hibernate.utils.HibernateUtils;
/*
* Hibernate工具類的一個測試
*/
public class HibernateDemo02 {
@Test
// 查詢:
public void demo02() {
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();// 創建數據庫事務對象開啓事務
// 使用load方法查詢
Customer customer = session.load(Customer.class, 1l);//發送SQL語句
System.out.println(customer);
tx.commit();// 提交事務
session.close();
}
}
C、修改方法
void update(Object obj);
第一種修改方式(覆蓋所有的值,包括沒有修改的值,如果沒有設置,則會被賦予null)
public void demo03() {
Session session = HibernateUtils.openSession();// 獲取數據庫的鏈接
Transaction transaction = session.beginTransaction();// 開啓事務
// 1、創建對象進行修改 只是修改一個的話其他沒有設置對應的值會別默認覆蓋爲null
Customer customer = new Customer();
customer.setCust_id(1l);
customer.setCust_name("王村");
session.update(customer);
transaction.commit();// 提交事務
session.close();// 關閉鏈接
}
第二種修改方式(先查詢然後再修改)
// 修改操作
public void demo03() {
//session可以理解爲是將數據放入到session對象當中
Session session = HibernateUtils.openSession();// 獲取數據庫的鏈接
Transaction transaction = session.beginTransaction();// 開啓事務
// 1、創建對象進行修改 只是修改一個的話其他沒有設置對應的值會別默認覆蓋爲null
/*
* Customer customer = new Customer(); customer.setCust_id(1l);
* customer.setCust_name("王村"); session.update(customer);
*/
// 先查詢,在修改(一般推薦使用先查詢再修改的方式)
Customer customer = session.get(Customer.class, 1l);//先將數據庫當中對應id的數據查詢出來方到customer對象當中
customer.setCust_name("王小鍵");//將對應的數據存放到查詢到的對象當中
session.save(customer);//再次將該對象放入到數據庫當中
transaction.commit();// 提交事務
session.close();// 關閉鏈接
}
D、刪除方法
void delete(Object obj);
第一種刪除方式
// 刪除操作
public void demo4() {
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//直接創建對象,刪除
Customer customer = new Customer();
customer.setCust_id(1l);
session.delete(customer);//刪除對應id的數據
//直接創建再刪除
tx.commit();
session.close();
}
第二種刪除方式
// 刪除操作
public void demo4() {
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//直接創建對象,刪除
/*
* Customer customer = new Customer(); customer.setCust_id(1l);
* session.delete(customer);//刪除對應id的數據
*/
//先查詢再刪除
Customer customer = session.get(Customer.class, 2l);//將數據當中的數據與Customer字節碼文件進行匹配
session.delete(customer);//刪除查詢到的customer對象
tx.commit();
session.close();
}
E、保存或更新
void saveOrUpdate(Object obj);
第一種沒有設置id(保存)
會單純的實現保存功能在已有的數據後面
@Test
// 保存
public void demo05() {
Session session = HibernateUtils.openSession();
Transaction transaction = session.beginTransaction();
Customer customer = new Customer(); customer.setCust_name("王菲");
session.saveOrUpdate(customer);
transaction.commit();
session.close();
}
設置id並且是數據表當中已有的id(會實現更新該數據)
會覆蓋對應的數據如果沒有設置會覆蓋爲null
@Test
// 更新
public void demo05() {
Session session = HibernateUtils.openSession();
Transaction transaction = session.beginTransaction();
Customer customer = new Customer();
customer.setCust_id(3l);
customer.setCust_name("李芬");
session.saveOrUpdate(customer);
transaction.commit();
session.close();
}
F、查詢所有
void createQuery(“from Customer”);
// 查詢所有
public void demo06() {
// 加載核心配置文件hibernate.cfg.cml
Configuration configuration = new Configuration().configure();
// 創建sessionFactory對象,類似於JDBC當中的連接池
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 通過sessionFactory獲取session對象,類似於我們JDBC中的Connection
Session session = sessionFactory.openSession();
// 手動開啓事務
Transaction transaction = session.beginTransaction();
// 接收一個HQL:Hibernate Query Language 面向對象的查詢語言
Query query = session.createQuery("from Customer");
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer);
}
System.out.println("====================================");
// 同時也可以使用SQL語句
SQLQuery createSQLQuery = session.createSQLQuery("select * from cst_customer");
List<Object[]> list2 = createSQLQuery.list();
for (Object[] objects : list2) {
System.out.println(Arrays.toString(objects));
}
transaction.commit();// 提交事務
session.close();// 關閉鏈接池
}
四、Transaction:事務對象
Transaction 接口是一個可選的API,可以選擇不使用這個接口,取而代之的是Hibernate 的設計者自己寫的底層事務處理代碼。
Transaction 接口是對實際事務實現的一個抽象,這些實現包括JDBC的事務、JTA
中的UserTransaction、甚至可以是CORBA
事務。之所以這樣設計是能讓開發者能夠使用一個統一事務的操作界面,使得自己的項目可以在不同的環境和容器之間方便地移植。
Hibernate當中去管理事務的對象。
對應文檔當中的方法
常用方法:
1、commit():提交事務
2、rollback ():回滾事務