1. 程式人生 > >hibernate 基本的CRUD增刪改查方法

hibernate 基本的CRUD增刪改查方法

hibernate核心api 有6大類
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() 清除方法,可以將持久態變為遊離態物件