本篇博客由hibernate核心接口说起,把它当做引子,从而引出自己对接口的亲身感受。
了解hibernate核心接口,清楚hibernate的结构组成
介绍结构
业务逻辑层
是hibernate2.0的东西,因为有侵入性,所以逐渐被淘汰或者说是另辟蹊径。如果想要Lifecycle的功能,完全可以使用Interceptor取而代之。
侵入性也就是要求我们必须继承些hibernate的东西,而java是单继承,所以具有侵入性的类扩展性不好,这就是常说的,鼓励pojo(plain ordinary java object)编程。
Configuration
概述:Configuration 类负责管理Hibernate 的配置信息。它包括如下内容:
Hibernate运行的底层信息:数据库的URL、用户名、密码、JDBC驱动类,数据库Dialect,数据库连接池等。
Hibernate映射文件(*.hbm.xml)。
Hibernate配置的两种方法:
属性文件(hibernate.properties),原始。
调用代码:Configuration cfg = new Configuration();
Xml文件(hibernate.cfg.xml)。
调用代码:Configuration cfg = new Configuration().configure();
SessionFactory
概述:
应用程序从SessionFactory(会话工厂)里获得Session(会话)实例。它在多个应用线程间进行共享。通常情况下,SessionFactory的创建非常消耗资源,整个应用一般只要一个SessionFactory就够了,只有多个数据库的时候才会使用多个SessionFactory。
会话工厂缓存了生成的SQL语句和Hibernate在运行时使用的映射元数据。
调用代码:
SessionFactory sessionFactory = cfg.buildSessionFactory();
说明:SessionFactory由Configuration对象创建,所以每个Hibernate配置文件,实际上是对SessionFactory的配置
Session(会话)
概述:
Session不是线程安全的,所以一般一线程一session。它代表与数据库之间的一次操作。
Session也称为持久化管理器,因为它是与持久化有关的操作接口。
Session通过SessionFactory打开,事务提交后就该关闭,否则再使用可能会发生问题。
它与Web层的HttpSession没有任何关系。
Session和事务应该能够统一管理。(Spring为Hibernate提供了非常好的支持)
调用代码
Session session = sessionFactory.openSession();
Query(查询)
允许你在数据库上执行查询并控制查询如何执行。
举例分析
Configuration、SessionFactory、Session、Transaction接口配合使用实现jdbc中的insert操作。
这是在上篇博客——学习ORM框架—hibernate(一):初识hibernate基础之上进行的,上篇博客已经由Object映射到了Relation,也就是说数据库表已经建立。
public static void testSave(String[] args) {
//读取hibernate.cfg.xml文件
Configuration cfg = new Configuration().configure();
//建立SessionFactory
SessionFactory factory = cfg.buildSessionFactory();
//取得session
Session session = null;
try {
session = factory.openSession();
//开启事务
session.beginTransaction();
User user = new User();
user.setName("张三");
user.setPassword("123");
user.setCreateTime(new Date());
user.setExpireTime(new Date());
//保存User对象
session.save(user);
//提交事务
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
//回滚事务
session.getTransaction().rollback();
}finally {
if (session != null) {
if (session.isOpen()) {
//关闭session
session.close();
}
}
}
}
}
其中Session session = factory.openSession();
watch下factory.openSession()的结果为:"factory.openSession()"= SessionImpl (id=63)。
可见得到的结果为session接口的实现SessionImpl,也就是父类引用指向了子类对象。
Session接口可以有多种实现,其中SessionImpl就是hibernate做的实现,如果想要使用SessionImpl2,只需修改配置文件这么简单,这就是最常用的抽象工厂,如果这点不清楚,请参见反射机制剖析(一):谈谈工厂家族、反射机制剖析(二): 利用抽象工厂实现BeanFactory。
我理解的接口
既有趣又值得深思的j2ee规范出台背景
当时几乎所有要厂商都推出了、或是正在赶制自己的应用服务器产品,但这个“应用服务器”究竟应该是什么东西,竞争者们又各有表述、莫衷一是。而sun‘公司却制定了j2ee规范,从而各项分支技术在这个领域中的地位和作用得到了客观、准确的定义。所以,sun非常具有远见卓识的,值得钦佩和学习。
接口就是规范
一个java程序既可以部署在jboss,也可以部署在bean weblogic,因为他们都实现j2ee规范,或者说实现了相同的接口。
一个老生常谈的例子就是JDBC。
很多人费解:既然我每连接一种数据库(如mysql)都要事先部署驱动程序,那我直接访问驱动程序不就行了?还
要JDBC干吗?
实际上,JDBC已经起了至关重要的作用了:正因为驱动程序是按照JDBC所规定的方法编写的,你才可以按照
JDBC的方式去使用。
换句话说,如果驱动程序提供者不按照JDBC标准来编写,而是按它自己独创的方式编写,那么你在使用驱动程序
的时候就要花时间查看驱动程序的文档以搞清楚用法。而当你日后决定使用另一种数据库的时候,这种数据库的驱
动程序也不是按照JDBC编写的,你又得去搞清楚另一套完全不同的用法,而你的所有代码都必须做相应的更改。
这种代价是不可想象的。
而现在的情况是,驱动程序提供者都按照JDBC规定的方式来编写,程序员都按照JDBC规定的方式来使用。程序员
不用关心自己正在使用何种数据库,而驱动程序编写者也不用费尽心力去编写接口文档来向程序员解释驱动程序的
用法,大家都向标准看齐就行了。
有了规范,让我们有依可循。比如在团队合作时,层与层之间定义好了接口,我在U层调用B层的接口方法,即使层
是否做了实现,我并不知道。所以层与层之间制定接口也是一件很有具有把控的任务。
无规范不成方圆,生活中也有太多的例子。当你正在你的键盘上打字的时候,你是否想到,你在学校就学会了的打
字方法至今还在用,因为所有计算机键盘的布局都是一样的。这时,你会不会由衷地感激这个设计键盘布局的人呢?
正是他让你只要学会一种打字方法就可以用在所有计算机的键盘上。