天天看點

Hibenate中建構單态Session完成增删改查操作

首先Gd要說一句,在真正的實踐項目中是不建議建構單态的Session的,最好是先建構一個單态的SessionFactory,再在所用的方法中擷取Session,因為Session是非線程安全的,如果建構單态的Session容易造成資料混亂,而且Session對象是輕量級對象,和SessionFactory相比不會占用太多資源。

對于像我這樣的初學者來說,Hibernate中每當建立一個方法完成資料庫的增删改查操作時都需要建立一個Session對象,這樣會使代碼顯得稍有繁雜,像我們平時學習和做練習的時候還好一些,如果到了大型的項目實踐中,未免顯得非常麻煩。

老師上課時談到,建構單态的Session有兩種方法,一種是使用靜态代碼塊,一種是使用私有化構造方法,課本上提到了靜态代碼塊的執行個體,是以我決定兩種方式都嘗試一下。

通過查閱書籍和檢視網上的資料發現使用私有化構造方法建構單态的Session的主要思路就是像它的描述一樣——私有化構造方法,類之中的所有屬性隻有在調用構造方法執行個體化對象之後才會配置設定空間,如果将構造方法私有化,在類的外部便無法通路,是以我們需要定義一個公有類型的方法使外部能夠通路到被私有化的構造方法。我們都知道構造方法是在建立對象時自動調用的,是以要通路構造方法,少不了要定義一個對象,使用公有類型的方法傳回所建立的對象,便能夠自動調用此類中的構造方法了,再在類中執行個體化一個Session對象,便能夠實作一處執行個體,多處調用了。

使用靜态代碼塊的道理和使用私有化構造方法類似,都是一處執行個體化,多處調用的思想。

下面是我的代碼、測試過程和結果:

私有化構造方法建構單态Session:

import org.User.User;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

class Singleton {
	private static Singleton intance = new Singleton();
	private Singleton(){}
	public static Singleton getInstance()
	{
		return intance;
	}
	public Session Cs()
	{
		
		return new Configuration().configure().buildSessionFactory().openSession();
	}
	
}

public class DemoSingleton{
@Test
public void testIncrease(){
	Singleton s = Singleton.getInstance();
	Session session = s.Cs();
	Transaction tx = session.beginTransaction();
	try {
		User u = new User();
		u.setName("小巴");
		u.setAge(18);
		u.setPassword("aiweigege");
		session.save(u);
		tx.commit();
	} catch (Exception e)
	{
		// TODO: handle exception
		if(null!=tx){tx.rollback();}
		e.printStackTrace();
	}
	finally
	{
		session.close();
	}
}
@Test
	public void updateTest()
	{
		Singleton s = Singleton.getInstance();
		Session session = s.Cs();
		Transaction tx = session.beginTransaction();
		try {
		User u = (User)session.get(User.class, new Integer(1));
		u.setName("張三");
		u.setAge(30);
		u.setPassword("123456");
		session.saveOrUpdate(u);
		tx.commit();
		} catch (Exception e) {
		if(tx!=null)
		{
			tx.rollback();
		}
			e.printStackTrace();
		}
		finally
		{			
			session.close();
		}
	}
@Test	
	public void testFind()
	{
		Singleton s = Singleton.getInstance();
		Session session = s.Cs();
		Transaction tx = session.beginTransaction();
		try {
			User u = (User) session.get(User.class, new Integer(1));
			System.out.println(u);
			tx.commit();
		} catch (Exception e) {
			if(tx!=null)
			{
				tx.rollback();
			}
			e.printStackTrace();
		}
		finally{
			session.close();
		}
	}
@Test	
	public void testDeleteById()
	{
		Singleton s = Singleton.getInstance();
		Session session = s.Cs();
		Transaction tx = session.beginTransaction();
		try {
			User u = (User) session.get(User.class, new Integer(1));
			session.delete(u);
			tx.commit();
		} catch (Exception e) {
			// TODO: handle exception
			if(tx!=null)
			{
				tx.rollback();
			}
			e.printStackTrace();
		}
		finally
		{
			session.close();
		}
	}
}           

靜态代碼塊實作單态Session:

import org.User.User;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
class StaSingleton {
	private static final Configuration config;
	private static final SessionFactory factory;
	static{
		config = new Configuration().configure();
		factory = config.buildSessionFactory();
	}
	//擷取Session
	public static Session getSession()
	{
		return factory.openSession();
	}
}

public class TestStaSingleton
{
	@Test
	public void testIncrease(){
	StaSingleton ss = new StaSingleton();
	Session session = ss.getSession();
	Transaction tx = session.beginTransaction();
		try {
			User u = new User();
			u.setName("趙六");
			u.setAge(18);
			u.setPassword("woshizhaoliu");
			u.setGender("男");
			session.save(u);
			tx.commit();
		} catch (Exception e)
		{
			// TODO: handle exception
			if(null!=tx){tx.rollback();}
			e.printStackTrace();
		}
		finally
		{
			session.close();
		}
	}
	@Test
	public void updateTest()
	{
	StaSingleton ss = new StaSingleton();
	Session session = ss.getSession();
	Transaction tx = session.beginTransaction();
		try {
			User u = (User)session.get(User.class, new Integer(2));
			u.setName("李四");
			u.setAge(32);
			u.setPassword("woshilisi");
			u.setGender("男");
			session.saveOrUpdate(u);
			tx.commit();
		} catch (Exception e) {
			if(tx!=null)
			{
				tx.rollback();
			}
			e.printStackTrace();
			}
			finally
			{			
				session.close();
			}
		}
	@Test	
	public void testFind()
	{
	StaSingleton ss = new StaSingleton();
	Session session = ss.getSession();
	Transaction tx = session.beginTransaction();
		try {
			User u = (User) session.get(User.class, new Integer(1));
			System.out.println(u);
			tx.commit();
		} catch (Exception e) {
			if(tx!=null)
			{
				tx.rollback();
			}
				e.printStackTrace();
			}
			finally{
				session.close();
			}
		}
	@Test	
		public void testDeleteById()
		{
		StaSingleton ss = new StaSingleton();
		Session session = ss.getSession();
		Transaction tx = session.beginTransaction();
		try {
			User u = (User) session.get(User.class, new Integer(4));
			session.delete(u);
			tx.commit();
		} catch (Exception e) {
				// TODO: handle exception
			if(tx!=null)
			{
					tx.rollback();
			}
				e.printStackTrace();
			}
			finally
			{
				session.close();
			}
	  }
}           

部分功能示範:

Hibenate中建構單态Session完成增删改查操作

資料庫表截圖:

Hibenate中建構單态Session完成增删改查操作

在更新資料的時候發現報出了這樣一個Error:

identifier of an instance of org.User.User was altered from 1 to 15

在網上找了一陣子還是沒能發現到底錯在哪裡,最後仔細看了看自己的代碼,發現是在更新操作的時候調用了實體類的setId()方法設定了id,将那一行删去之後便測試成功了,大家可不要像我一樣粗心大意哦!