hibernate 基本的CRUD增刪改查方法
Session SessionFactory Transcation Query Criteria Configuration
1.Session介面負責執行被持久化物件的CRUD操作,非執行緒安全的
2.SessionFactory介面負責初始化Hibernate。它充當資料儲存源的代理,並負責建立Session物件。
3.TransactionTransaction 介面是一個可選的API,處理事務的
4.Query介面讓你方便地對資料庫及持久物件進行查詢,它可以有兩種表達方式:HQL語言或本地資料庫的SQL語句。
5.Criteria介面與Query介面非常類似,允許建立並執行面向物件的標準化查詢。
6.Configuration 類的作用是對Hibernate 進行配置,以及對它進行啟動。它是啟動hibernate 時所遇到的第一個物件。
用他建立一個SessionFactory物件。
=====================================================
Hibernate 中提供了兩級Cache(高速緩衝儲存器),
第一級別的快取是Session級別的快取,其實就是一個map物件,在記憶體中,一般不用管理,事務級的快取
第二級別的快取是SessionFactory級別的快取,在記憶體和硬碟中,可以配置和更改可以動態載入和解除安裝。程序級的快取
=====================================================
hibernate的3種狀態
瞬時transient
持久persistent
遊離datached
這三種狀態就是物件在session和資料庫中的存在關係,屬於一級快取範圍
瞬時狀態就是剛new出來一個物件,還沒有被儲存到資料庫中,即資料庫中沒有session中也沒有。
持久化狀態就是已經被儲存到資料庫中,並在Session中,即資料庫中有session中也有
離線狀態就是資料庫中有,但是session中不存在該物件
瞬時狀態(臨時狀態):
new 出來的物件
delete()
持久狀態:
物件被 save() get() load() find() iterator()
update() saveOrUpdate() merger() lock()
遊離狀態:
evict() close() clear()
程式碼演示==================================================
Student實體類
package cn.hibernate.entity; import java.io.Serializable; /** * Student實體類 * @author Administrator * */ public class Student implements Serializable{ private static final long serialVersionUID = 1234L; private int id; // OID private String name; //姓名 private String clazz; //科目 private int score; //分數 public Student(int id, String name, String clazz, int score) { super(); this.id = id; this.name = name; this.clazz = clazz; this.score = score; } public Student( String name, String clazz, int score) { super(); this.name = name; this.clazz = clazz; this.score = score; } public Student() { super(); } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getClazz() { return clazz; } public void setClazz(String clazz) { this.clazz = clazz; } public int getScore() { return score; } public void setScore(int score) { this.score = score; } }
dao層 資料訪問層
package cn.hibernate.dao; import java.io.Serializable; import org.hibernate.Session; import cn.hibernate.common.HibernateSessionFactory; import cn.hibernate.entity.Student; /** * 資料訪問層 * @author Administrator * */ public class StudentDao { //新增 public void add(Student stu){ try { HibernateSessionFactory.getSession().save(stu); } catch (Exception e) { // System.out.println("新增失敗"+e); throw new RuntimeException("新增失敗",e); } } //修改 public void update(Student stu){ try { HibernateSessionFactory.getSession().update(stu); } catch (Exception e) { throw new RuntimeException("修改失敗",e); } } //新增or修改 public void saveOrUpdate(Student stu){ try { HibernateSessionFactory.getSession().merge(stu); } catch (Exception e) { throw new RuntimeException("修改失敗",e); } } //根據id 返回student物件 public Student get(Serializable id){ return HibernateSessionFactory.getSession().get(Student.class,id); } public Student load(Serializable id){ return HibernateSessionFactory.getSession().load(Student.class,id); } public Student find(Serializable id){ return HibernateSessionFactory.getSession().find(Student.class,id); } public void delect(Student stu){ HibernateSessionFactory.getSession().delete(stu); } public void close(){ HibernateSessionFactory.getSession().clear(); } public void evict(Student stu){ HibernateSessionFactory.getSession().evict(stu); } }
biz層 業務處理層
package cn.hibernate.biz;
import java.io.Serializable;
import org.hibernate.Session;
import org.hibernate.Transaction;
import cn.hibernate.common.HibernateSessionFactory;
import cn.hibernate.dao.StudentDao;
import cn.hibernate.entity.Student;
//業務處理層
public class StudentBiz {
private StudentDao dao = new StudentDao();
public void evict(Student stu){
Transaction tx = null;
try {
tx = HibernateSessionFactory.getSession().beginTransaction();
dao.evict(stu);
tx.commit();
} catch (Exception e) {
if(tx!=null){
tx.rollback();//回滾事務
}
}
}
public void delete(Student stu){
Transaction tx = null;
try {
tx = HibernateSessionFactory.getSession().beginTransaction();
dao.delect(stu);
tx.commit();
} catch (Exception e) {
if(tx!=null){
tx.rollback();//回滾事務
}
}
}
public Student getStu(Serializable id){
Transaction tx = null;
Student stu = null;
try {
tx = HibernateSessionFactory.getSession().beginTransaction();
stu = dao.find(id);
dao.close();
stu.setClazz("php");
tx.commit();
} catch (Exception e) {
if(tx!=null){
tx.rollback();//回滾事務
}
}
return stu;
}
public void saveOrUpdate(Student stu){
Transaction tx = null;
try {
tx = HibernateSessionFactory.getSession().beginTransaction();
dao.saveOrUpdate(stu);
stu.setName("meger111");
tx.commit();
} catch (Exception e) {
if(tx!=null){
tx.rollback();//回滾事務
}
}
}
public void update(Student stu){
Transaction tx = null;
try {
tx = HibernateSessionFactory.getSession().beginTransaction();
dao.update(stu);
tx.commit();
} catch (Exception e) {
if(tx!=null){
tx.rollback();//回滾事務
}
}
}
public void addStu(Student stu){
Transaction tx = null;
try {
tx = HibernateSessionFactory.getSession().beginTransaction();
dao.add(stu);
/**
* 此時stu是持久化狀態,已經被session所管理,當在提交時,會把session中的物件和目前的物件進行比較
* 如果兩個物件中的值不一致就會繼續發出相應的sql語句
*/
tx.commit();
System.out.println("新增成功");
} catch (Exception e) {
if(tx!=null){
tx.rollback();//回滾事務
}
}
}
}
讀取配置檔案類
package cn.hibernate.common;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
/**
* 讀取配置檔案的類
* @author Administrator
*
*/
public class HibernateSessionFactory {
private static Configuration cfg; //讀取配置檔案
private static SessionFactory sessionfactory;//連結資料庫的會話工廠 只建立一次
static {
try {
cfg = new Configuration().configure();
// Properties props = cfg.getProperties();
// props.list(System.out);
sessionfactory = cfg.buildSessionFactory();
// Map<String, Object> properties = sessionfactory.getProperties();
// for(Map.Entry<String,Object> entry : properties.entrySet()){
// System.out.println(entry.getKey()+";;;"+entry.getValue());
//
// }
// System.out.println(sessionfactory);
} catch (HibernateException e) {
throw new RuntimeException("初始化失敗",e);
}
}
//建立session時和執行緒繫結,每個使用者得到是唯一的session 需要事務才可以操作
public static Session getSession(){
Session currentSession = null;
try {
currentSession = sessionfactory.getCurrentSession();
// System.out.println("session:"+currentSession);
} catch (HibernateException e) {
// System.out.println("建立session 失敗!"+e);
throw new RuntimeException("建立session 失敗!",e);
}
return currentSession;
}
}
test測試類
package cn.hibernate.test;
import cn.hibernate.biz.StudentBiz;
import cn.hibernate.entity.Student;
public class Test {
public static void main(String[] args) {
Student stu = new Student();
stu.setId(2);
StudentBiz biz = new StudentBiz();
biz.evict(stu);
}
}
方法比較
get() 和load()方法
這兩個方法都可以獲取類例項物件,但是get()方法是直接從資料庫獲取,load()先從session一級快取(記憶體)中查詢再到二級快取中查詢最後才到資料庫
get()方法不受配置檔案是否懶載入約束,load()方法查詢需要結合配置檔案是否為懶載入查詢,由於預設情況下對映配置檔案為懶載入模式,即lazy='"true",
所以當事務提交後session就結束了,後續如果對實體物件進行其他操作都不會更新到資料庫裡,而且獲取到的實體物件如果沒有儲存獲取物件操作,則最後關閉session後想要獲取物件就會報session 為null .
修改建議在對映配置檔案中class 類新增引數 lazy = "false" 但是這種方法的弊端就是執行效率低
第二種修改可以用OpenSessionInViewFilter 在web.xml中進行配置,同一管理session的開啟和關閉 當有請求發出時 session開啟,當響應結束 session結束
============================================================================================================
merger()和saveOrUpdate()方法比較
當呼叫merger()方法時,如果實體類沒有id 則會呼叫save()方法,利用hibernate配置檔案中id建立規則建立類物件,如果有id且資料庫存在該id,則update()更新資料和saveOrUpdate()方法一致。但是merger()方法對實體類不會變為持久態persistent,但是可以操作持久態資料,而saveOrUpdate()可以將遊離態資料變為持久態。且saveOrUpdate方法必須指明主鍵id
該物件需要是遊離態物件才可以呼叫 轉成持久態。
close()方法為關閉session,事務,可以將持久態變為遊離態物件,當呼叫該方法後 提交事務就會報錯
clear() 清除方法,可以將持久態變為遊離態物件