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

Hibernate 模板設(shè)計(jì)模式

1. 前言

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

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

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

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

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

2.1 什么是模板化操作

OOP 中有一個(gè)編碼原則 : 寫(xiě)僅寫(xiě)一次 。翻譯過(guò)來(lái)就是,不要重復(fù),要重用。

如何簡(jiǎn)化測(cè)試實(shí)例:

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

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

Spring 框架中就提供的有 Hibernate 模板對(duì)象。

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

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

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

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

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

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

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

2.2 模板化流程

先畫(huà)一個(gè)圖,簡(jiǎn)要說(shuō)一下模板化的基本思路:

圖片描述

一個(gè)模板對(duì)象中有 2 種類型代碼:

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

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

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

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

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

  1. 構(gòu)建一個(gè) 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)用者角色:此處為測(cè)試實(shí)例:
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. 控制臺(tái)輸出結(jié)果不再貼出。不要懷疑,結(jié)果一定是你所期望的。

模板對(duì)象中的接口非常重要:

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

模板對(duì)象中可以進(jìn)一步封裝 Session 對(duì)象中的相關(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;
}

測(cè)試實(shí)例:

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

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

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

3. 序列化

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

public class HibernateTemplate<T extends Serializable>{}

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

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

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

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

所謂序列化,通俗理解:

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

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

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

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

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

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

4. 小結(jié)

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

答案其實(shí)就在于你對(duì)這兩個(gè)方法的理解了。

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

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