赞
踩
本节课和大家一起使用模板设计模式重构 Hibernate 操作流程,通过本节课程内容,你将了解到:
学习 Hibernate 的过程,如同训练场上练兵。终有一天,你要奔赴真正的战场(真实项目)。
所以,随时随地,要审视代码、重构代码。
OOP 中有一个编码原则 : 写仅写一次 。翻译过来就是,不要重复,要重用。
如何简化测试实例:
答案是:使用模板设计模式进一步封装 Hibernate 的操作。
在真实项目中,Hibernate 仅仅只是完成项目中的一部分工作,需要和其它,如 Spring 等框架联合工作,一起承担整体项目的开发。
Spring 框架中就提供的有 Hibernate 模板对象。
模板设计模式的应用场景:
一个常规的、频繁的操作代码中,大部分代码不需要变动,只有小部分代码需要根据需求变动。这种场景下的代码,可认为是模板化操作流程代码,可使用模板设计模式进行重构。
JDBC 就是一个标准化的模板化操作过程。可以说,Hibernate 是一个操作 JDBC 的模板化框架。
Hiberante 虽然高度简化 JDBC 操作流程,但使用期间,还是需要按部就班的:
好无聊呀,重复的事情,总是让人很容易麻木。内心挣扎时刻,便是想办法应对时刻。
本文中把不需要改变的代码称为模板代码。
好了,现在开始,一起使用模板设计模式继续简化 Hibernate 的操作流程。这种感觉就像风一样自由。
先画一个图,简要说一下模板化的基本思路:
一个模板对象中有 2 种类型代码:
可以得出一个结论,对于一件事情,原来完全是靠调用者独立完成,现在分摊到了两个对象上,模板对象完成公共部分代码,调用者完成属于自己需求的代码。
有了上面的理解基础,便知,一个完整的模板调用过程,会涉及到 3 个角色:
下面进行具体实例编写:
1.构建一个 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;
- }
- }
2.接口角色:
- public interface Notify<T extends Serializable> {
- T action(Session session);
- }
3.调用者角色:此处为测试实例:
- 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());
4.控制台输出结果不再贴出。不要怀疑,结果一定是你所期望的。
模板对象中的接口非常重要:
模板对象中可以进一步封装 Session 对象中的相关方法,如:
- 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 常规流程外,具体操作时,直接上模板对象。
对于任何知识不要理所当然地接受,要善于发现代码中冗余的地方,逐步形成代码意识,随时改进代码。
不知道大家发现没有,模板对象的泛型声明:
public class HibernateTemplate<T extends Serializable>{}
前面课程使用 Session 对象中的方法时,Serializable 接口时不时的就蹦出来,为什么 Hibernate 要求持久化类实现 Serializable 接口?
为什么使用 Sesssion 的方法,某些参数也需要一个实现 Serializable 接口的对象。
- public Object load(Class theClass, Serializable id);
- public Object get(Class clazz, Serializable id);
原因很简单,如果你真正了解什么是序列化。
所谓序列化,通俗理解:
以二进制的形式存储对象中的数据,这个过程就叫序列化。相反的,把存储的二进制数据恢复成对象数据,这个过程是反序列化。
序列化的目的,就是要以对象为单元进行数据存储,存储并不限于本地磁盘,可以是网络等环境。
序列化屏蔽底层繁琐的编码、解码过程,完全以一种面向对象的理念进行数据存储。提高开发效率。
Hiberante 为什么要求持久化对象实现序列化?
不管怎样,让对象具有序列化能力,有点像《终结者》中的液态机器人,随时把自己液态化,来去自由。适应不同的需求场景。
本节课也要到说再见的时候,留一个问题给大家:如果在持久化类中重写 equals 方法,为什么也要求重写 hashCode 方法。
答案其实就在于你对这两个方法的理解了。
好了!本节课,和大家一起使用模板设计模式封装了 Hibernate 的操作代码。让 Hibernate 的使用过程变得更简单,更是为了适应真实项目需求。
本节课程也和大家一起聊到了持久化对象为什么要实现序列化接口。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。