1.
1.1 獲取Session的兩種方式
Session是Hibernate的核心,我們在創建了SessionFactory對象後,有兩種方式可以獲取Session實例
- Session session = sessionFactory.
openSession();
採用openSession方法獲取Session實例時,SessionFactory直接創建一個新的Session實例,並且在使用完成後需要調用close方法進行手動關閉。 - Session session = sessionFactory.
getCurrentSession();
而getCurrentSession方法創建的Session實例會被綁定到當前線程中,它在提交或回滾操作時會自動關閉。
1.2 Session的事務管理—Transaction對象
我們通過Session開啓事務,獲取Transaction
對象
//開啓事務
Transaction transaction = session.beginTransaction();
// 提交事務
transaction.commit();
// 回滾事務
transaction.rollback();
Session執行完數據庫操作後,要使用Transaction接口的commit()方法進行事務提交,才能真正的將數據操作同步到數據庫中。發生異常時,需要使用rollback()方法進行事務回滾,以避免數據發生錯誤。
由於Session對象屬於線程不安全,當一個線程有多個Session時,無法保證事務。所以一個線程要保障只有一個Session對象。
爲了保證一個線程中只有一個Session,所以在實際開發中,我們將Session綁定到當前線程中
1.3 get方法和load方法
Hibernate中get()和load()的區別
在hibernate.cfg.xml中開啓顯示SQL語句
<property name="hibernate.show_sql">true</property>
dao類
public class CustomerDao {
/**
* 根據id查詢客戶信息 get立即加載
*/
public static Customer findOneById(long id){
Session session = null;//Session對象
try{
// 查詢不需要開啓事務,只有對數據庫內容進行多次增刪改操作時
session = HibernateUtil.openSession();
Customer newCustomer = session.get(Customer.class, id);
return newCustomer;
}catch(Exception e){
e.printStackTrace();
}finally{
session.close();//釋放資源
}
return null;
}
/**
* 根據id查詢客戶信息 load延遲加載
*/
public static Customer loadOneById(long id){
Session session = null;//Session對象
try{
// 查詢不需要開啓事務,只有對數據庫內容進行多次增刪改操作時
session = HibernateUtil.openSession();
Customer newCustomer = session.load(Customer.class, id);
return newCustomer;
}catch(Exception e){
e.printStackTrace();
}finally{
session.close();//釋放資源
}
return null;
}
}
HibernateUtil
public class HibernateUtil {
private static SessionFactory factory;
// 使用靜態代碼塊獲取SessionFactory
static {
//細節:Hibernate把所有可預見的異常,都轉成了運行時異常(工具中不會提示要添加異常塊)
try {
// 加載hibernate.cfg.xml配置文件
Configuration config = new Configuration().configure();
factory = config.buildSessionFactory();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 獲取一個新的Session對象(每次都是一個新對象)
* @return
*/
public static Session openSession(){
return factory.openSession();
}
/**
* 獲取一個新的Session對象(每次都是一個新對象)
* @return
*/
public static Session getCurrentSession(){
return factory.getCurrentSession();
}
}
測試
@Test
public void testGet(){
Customer oneById = CustomerDao.findOneById(1L);
System.out.println("-------------------------");
System.out.println(oneById);
}
當get()方法被調用的時候就會立即發出SQL語句,使用get()和普通的單條查詢並沒有多大的區別。
2.Session、EntityManager、HibernateTemplate的區別
- Session是Hibernate操作數據庫的對象
- EntityManager是JPA操作數據庫的對象
- HibernateTemplate是Spring整合Hibernate後操作數據庫的對象(底層是session)