第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

Hibernate 模板設(shè)計模式

1. 前言

本節(jié)課和大家一起使用模板設(shè)計模式重構(gòu) Hibernate 操作流程,通過本節(jié)課程內(nèi)容,你將了解到:

  • 如何運用模板設(shè)計模式重構(gòu) Hibernate 操作流程;
  • 持久化對象與序列化接口;

2. 模板設(shè)計模式

學(xué)習(xí) Hibernate 的過程,如同訓(xùn)練場上練兵。終有一天,你要奔赴真正的戰(zhàn)場(真實項目)。

所以,隨時隨地,要審視代碼、重構(gòu)代碼。

2.1 什么是模板化操作

OOP 中有一個編碼原則 : 寫僅寫一次 。翻譯過來就是,不要重復(fù),要重用。

如何簡化測試實例:

答案是:使用模板設(shè)計模式進(jìn)一步封裝 Hibernate 的操作。

在真實項目中,Hibernate 僅僅只是完成項目中的一部分工作,需要和其它,如 Spring 等框架聯(lián)合工作,一起承擔(dān)整體項目的開發(fā)。

Spring 框架中就提供的有 Hibernate 模板對象。

模板設(shè)計模式的應(yīng)用場景:

一個常規(guī)的、頻繁的操作代碼中,大部分代碼不需要變動,只有小部分代碼需要根據(jù)需求變動。這種場景下的代碼,可認(rèn)為是模板化操作流程代碼,可使用模板設(shè)計模式進(jìn)行重構(gòu)。

JDBC 就是一個標(biāo)準(zhǔn)化的模板化操作過程??梢哉f,Hibernate 是一個操作 JDBC 的模板化框架。

Hiberante 雖然高度簡化 JDBC 操作流程,但使用期間,還是需要按部就班的:

  1. 創(chuàng)建配置對象;
  2. 創(chuàng)建會話工廠;
  3. 創(chuàng)建會話對象;
  4. 創(chuàng)建事務(wù)對象;
  5. 終于輪到完成需求;
  6. 嘿,記得…… 關(guān)閉會話對象!謝謝提醒,差點忘記了。

好無聊呀,重復(fù)的事情,總是讓人很容易麻木。內(nèi)心掙扎時刻,便是想辦法應(yīng)對時刻。

本文中把不需要改變的代碼稱為模板代碼
好了,現(xiàn)在開始,一起使用模板設(shè)計模式繼續(xù)簡化 Hibernate 的操作流程。這種感覺就像風(fēng)一樣自由。

2.2 模板化流程

先畫一個圖,簡要說一下模板化的基本思路:

圖片描述

一個模板對象中有 2 種類型代碼:

  • 模板代碼: 公共的代碼,不需要變更的代碼;
  • 通知代碼: 告訴調(diào)用者,此處應(yīng)該是你來做了。一般采用接口的方式進(jìn)行通知。

可以得出一個結(jié)論,對于一件事情,原來完全是靠調(diào)用者獨立完成,現(xiàn)在分?jǐn)偟搅藘蓚€對象上,模板對象完成公共部分代碼,調(diào)用者完成屬于自己需求的代碼。

有了上面的理解基礎(chǔ),便知,一個完整的模板調(diào)用過程,會涉及到 3 個角色:

  • 調(diào)用者角色: 使用者;
  • 模板角色: 封裝公共代碼,簡化使用者的操作;
  • 接口角色: 調(diào)用者和模板角色之間的連接通道,互相通信;

下面進(jìn)行具體實例編寫:

  1. 構(gòu)建一個 HibernateTemplate 類,模板角色:
public class HibernateTemplate<T extends Serializable > {
	private SessionFactory sessionFactory;
	public HibernateTemplate() {
		// 模板代碼
		Configuration configuration = new Configuration().configure();
		// 模板代碼
		ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties())
				.buildServiceRegistry();
		// 模板代碼
		sessionFactory = configuration.buildSessionFactory(serviceRegistry);
	}
	
	public T template(Notify<T> notify) {
		// 模板代碼
		Session session = sessionFactory.openSession();
		// 模板代碼
		Transaction transaction = null;
		try {
			// 模板代碼
			transaction = session.beginTransaction();
			// 通知代碼
            T result = notify.action(session);
			transaction.commit();
			return result;
		} catch (Exception e) {
			transaction.rollback();
		} finally {
			session.close();
		}
		return null;
	}
}
  1. 接口角色:
public interface Notify<T extends Serializable> {
	T action(Session session);
}
  1. 調(diào)用者角色:此處為測試實例:
HibernateTemplate<Student> hibernateTemplate=new HibernateTemplate<Student>();	
		Student stu= hibernateTemplate.template(new Notify<Student>() {
			@Override
			public Student action(Session session) {
				return (Student)session.get(Student.class, new Integer(1));
			}
		});
		System.out.println(stu.getStuName());
  1. 控制臺輸出結(jié)果不再貼出。不要懷疑,結(jié)果一定是你所期望的。

模板對象中的接口非常重要:

  • 通知作用,并等待調(diào)用者的響應(yīng)。接口中的方法也可稱為回調(diào)方法;
  • 模板對象通過接口的方式暴露出 Session 給調(diào)用者,調(diào)用者不需要關(guān)心 Session 是怎么來的,安心使用便是。

模板對象中可以進(jìn)一步封裝 Session 對象中的相關(guān)方法,如:

public T get(Class<?> clz, Serializable ser) {
	// 模板代碼
	Session session = sessionFactory.openSession();
	// 模板代碼
	Transaction transaction = null;
	try {
		// 模板代碼
		transaction = session.beginTransaction();
		T result = (T) session.get(clz, ser);
		transaction.commit();
		return result;
	} catch (Exception e) {
		transaction.rollback();
	} finally {
		session.close();
	}
	return null;
}

測試實例:

HibernateTemplate<Student> hibernateTemplate=new HibernateTemplate<Student>();	
		Student stu= hibernateTemplate.get(Student.class, new Integer(1));
		System.out.println(stu.getStuName());	

是不是開心的不要不要的,除了在模板類中需要寫一次 Hibernate 常規(guī)流程外,具體操作時,直接上模板對象。

對于任何知識不要理所當(dāng)然地接受,要善于發(fā)現(xiàn)代碼中冗余的地方,逐步形成代碼意識,隨時改進(jìn)代碼。

3. 序列化

不知道大家發(fā)現(xiàn)沒有,模板對象的泛型聲明:

public class HibernateTemplate<T extends Serializable>{}

前面課程使用 Session 對象中的方法時,Serializable 接口時不時的就蹦出來,為什么 Hibernate 要求持久化類實現(xiàn) Serializable 接口?

為什么使用 Sesssion 的方法,某些參數(shù)也需要一個實現(xiàn) Serializable 接口的對象。

public Object load(Class theClass, Serializable id);
public Object get(Class clazz, Serializable id);

原因很簡單,如果你真正了解什么是序列化。

所謂序列化,通俗理解:

以二進(jìn)制的形式存儲對象中的數(shù)據(jù),這個過程就叫序列化。相反的,把存儲的二進(jìn)制數(shù)據(jù)恢復(fù)成對象數(shù)據(jù),這個過程是反序列化。

序列化的目的,就是要以對象為單元進(jìn)行數(shù)據(jù)存儲,存儲并不限于本地磁盤,可以是網(wǎng)絡(luò)等環(huán)境。

序列化屏蔽底層繁瑣的編碼、解碼過程,完全以一種面向?qū)ο蟮睦砟钸M(jìn)行數(shù)據(jù)存儲。提高開發(fā)效率。

Hiberante 為什么要求持久化對象實現(xiàn)序列化?

  • 緩存數(shù)據(jù): 如先把一個查詢出來的對象數(shù)據(jù)以序列化的方式存儲到內(nèi)存或磁盤中,需要時再讀出來,再持久化到數(shù)據(jù)庫中;
  • 網(wǎng)絡(luò)數(shù)據(jù)傳輸: 需要把持久化數(shù)據(jù)從一個系統(tǒng)傳到另一個系統(tǒng)時,可能兩個系統(tǒng)是基于兩個平臺,在異構(gòu)化的系統(tǒng)中通過二進(jìn)制進(jìn)行數(shù)據(jù)傳遞,可打破這種壁壘。

不管怎樣,讓對象具有序列化能力,有點像《終結(jié)者》中的液態(tài)機(jī)器人,隨時把自己液態(tài)化,來去自由。適應(yīng)不同的需求場景。

4. 小結(jié)

本節(jié)課也要到說再見的時候,留一個問題給大家:如果在持久化類中重寫 equals 方法,為什么也要求重寫 hashCode 方法。

答案其實就在于你對這兩個方法的理解了。

好了!本節(jié)課,和大家一起使用模板設(shè)計模式封裝了 Hibernate 的操作代碼。讓 Hibernate 的使用過程變得更簡單,更是為了適應(yīng)真實項目需求。

本節(jié)課程也和大家一起聊到了持久化對象為什么要實現(xiàn)序列化接口。