Hibernate常用接口
Hibernate的接口类型
在了解了Hibernate的基本配置,映射文件后,道路已经铺平了。我们继续往前走。接下来,我们应该做的是了解Hibernate常用的接口,对Hibernate的工作方式进一步熟悉,为我们下一步的编码做好充分的准备。
ORM是复杂的,可以看看Hibernate发布里的javadoc,100+MB。如果我们单单去阅读它的API,估计一年你才能看完。然而,我们仅仅是使用他,并不需要对它了解的十分完全。我们只需要了解它的常用核心类和接口就行了。就像数据库是非常复杂的,然而我们仅仅是使用它,又不需要关心它的底层实现,建表还是很easy的。
同样Hibernate在设计的时候,也考虑到广大使用者,因此它的API接口设计还是相对简单的。Hibernate的接口大致可以分为以下几种类型:
基本操作类:用来完成对数据库增、删、改、查的接口。例如:Session、Transaction和Query;
配置类:Hibernate用例读取配置文件和映射文件的接口。例如:SessionFactory、Configuration;
回调接口:它允许应用程序能对一些事件的发生作出相应的操作。例如:Interceptor、Validatable;
扩展映射机制接口:UserType、CompositeUserType、IdentifierGenerator
Hibernate六个常用接口
Hibernate的类非常多,但我们常用的也就六个,分别是:
Configuration、SessionFactory、Session、Transaction、Query、Criteria。这六个核心接口是我们必须了解和掌握的。通过这六个接口,我们可以完成对数据的基本操作,包括增、删、改、查,还有事务控制。
这六个接口之间的产生关系如下:
Configuration类
org.hibernate.cfg.Configuration接口的作用是对Hibernate进行配置,以及对它进行启动。在Hibernate的启动过程中,Configuration类的实例首先读取Hibernate配置文件,加载配置信息,然后加载映射文件,创建一个SessionFactory对象。
实例被设计成启动期间(startup-time)对象,一旦SessionFactory 创建完成它就被丢弃了。
要使用一个Configuration对象,要为它设置两个方面的内容:
- 数据库连接属性
- hbm.xml或pojo类
Configuration常用操作函数
1.加载Hibernate配置文件
Configuration cfg=new Configuration().configure("/etc/hibernate.cfg.xml");
或者
Configuration cfg=new Configuration().configure("/etc/hibernate.properties");
2.为Configuration指定映射文件
cfg.addResource("test/User.hbm.xml");
3.为Configuration指定POJO类,Order.hbm.xml根Order.java一个目录
cfg.addClass(test.Order.class);
4.为Configuration指定Hibernate配置属性,当然我们加载了配置文件就不能使用这个方法了。
Configuration cfg = new Configuration()
.addClass(test.User.class)
.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect")
.setProperty("hibernate.connection.datasource", "java:comp/env/jdbc/test")
.setProperty("hibernate.order_updates", "true");
5.获得SessionFactory
SessionFactory sessions = cfg.buildSessionFactory();
当所有映射定义被 Configuration 解析后,应用程序必须获得一个用于构造org.hibernate.Session 实例的工厂SessionFactory。这个工厂将被应用程序的所有线程共享,线程安全的全局对象,只需要被实例化一次。单例模式。
Hibernate 允许你的应用程序创建多个SessionFactory 实例。这对使用多个数据库的应用来说很有用。
SessionFactory接口
Hibernate 的SessionFactory是一个关联于特定数据库全局的工厂(factory)。如果你要使用多个数据库,就要用多个的SessionFactory,通常把它们放在多个配置文件(Hibernate.cfg.xml)中(为了更容易启动)。
SessionFactory不是轻量级的对象,它包含与指定数据连接各种配置信息,是个线程安全的全局对象,只需要被实例化一次。我们不应该在应用程序中多次实例化它。
Session接口
Session接口是我们最常用的一个接口。但Session是一个轻量级的类,创建和销毁它并不会占用很多资源。请注意,Session对象是非线程安全的,因此在你的设计中,最好一个线程只创建一个Session对象。
Session主要用来管理对数据库进行的操作,包括开启一个事务、存取对象、执行查询。一般可以将Session看成一个对象的缓冲区或持久层管理器,当持久对象被Session管理后,Hibernate在事务提交时能够自动检测缓冲区的持久化对象是否已经改变,也就是说持久化对象所携带的信息是否发生了改变(脏数据检查),然后与数据库进行同步操作。
对象的三种状态,其实这里指对象与Session关系的三种状态:
Transient(自由状态):不曾进行持久化,数据库中没记录,也就是说没有与Session发生过关联。
Persistent(持久状态):持久的实例在数据库中有对应的记录,并且在Session的缓存中。
Detached(游离状态):持久的实例在数据库中有对应的记录,但不在Session的缓存中。也就是说曾经与Session发生过关联。
三种状态的转化:
这让我想到了一个恰当的比喻:对象和Session的关系就像我们与大学的关系:
自由状态是我们没上大学;
持久状态是我们已经被录取,并且在就读;
游离状态是我们已经毕业了,飞走了,但你依然是你母校的学生!
当然,你可以选择再次深造!
Transaction接口
这个API是可选的,我们可以选择使用该类来添加事务支持。它是对实际事务实现的一个抽象,这些实现包括JDBC事务、JTA中的UserTransaction、甚至是CORBA事务。之所以这样设计,是为了开发者能够使用一个统一的事务操作界面,是的自己的项目可以在不同的环境和容器之间方便的移植。
一个典型的事务应该使用下面的形式,beginTransaction()到commit()之间的代码处在同一个事务:
beginTransaction()开启事务;
commit()提交事务;
rollback()在发生异常时回滚事务。
下面的session使用sessionFactory.openSession()方式取的:
Transaction tx = null; try { tx = session.beginTransaction(); // do some work tx.commit(); } catch (RuntimeException e) { if (tx != null) tx.rollback(); throw e; // or display error message } finally { session.close(); }
下面的session使用sessionFactory.getCurrentSession()方式取的:
Transaction tx = null; try { tx = session.beginTransaction(); // do some work tx.commit(); } catch (RuntimeException e) { tx.rollback(); throw e; // or display error message }
Query和Criteria接口
这两个接口负责执行各种查询,它可以使用HQL和SQL语句两种表达方式。由Session创建并执行。
Criteria接口与Query接口非常类似,它允许创建并执行面向对象的标准化查询。
数据库操作中查询是使用最频繁的,是非常重要的一块,我们在以后详细讨论。