对Hibernate的几个对象的理解
-完成了配置文件的步骤以后,在使用Hibernate的使用过程中会用到一些类,对这些类做一个简单的汇总理解
1.Configuration
这个是我们在使用Hibernate的时候用到的第一个对象了,他的主要作用是用来加载我们所配置的核心配置文件,具体的加载过程有如下三种形式:
//加载Hibernate的默认核心配置hibernate.cfg.xml文件,常用方式
new Configuration().Configure();
//加载给定路径下的核心配置文件
new Configuration().configure(String path);
//将给定路径下的文件作文映射文件的形式加入,相当于在核心配置文件使用mapping标签引入映射文件
new Configuration().addResource(String path);
在加载完毕核心配置文件之后,我们可以通过该对象返回接下来要说的sessionFactory对象
2.SessionFactory
可以通过该对象来获取Session对象并进行后续操作,如上面说说的那样,SessionFactory对象可以使用Configuration对象的 buildSessionFactory() 方法获取,如果在核心配置文件里面配置了hbm2ddl.auto选项,那么在获取之前会根据设定的值对数据库的表进行相关操作,这一过程是比较耗费资源的。所以该对象在使用的时候我们可以将其设置为单例的形式,使其以一个全局对象的形式存在,获取Session的工厂,一个就够了。当然为了便于以后通过它更方便的获取Session对象,可以将其简单的封装为一个辅助类的形式存在:
public class HibernateUtil {
private static final SessionFactory sessionFactory = null;
static {
try {
sessionFactory = new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
这个对象在我现在的认知中,就是作为一个工厂存在,我们后续使用Session的对象话,直接通过该工厂就可以取得,那么什么又是Session对象呢?
3.Session对象
首先,它不是Http中的那个Session,不是用来保存会话信息的。其次,这个对象是通过SessionFactory获取的,一个Session就是一个单一的工作单元,它不像SessionFactory对象可以在一个项目中被共用,Session对象是线程不安全的,因此一个Session对象仅仅只能服务于一个操作。以这二者举个例子,像卖内裤的商店,任何人都能通过该商店购买内裤。但是具体到某一条内裤,只能由一人使用,当然啦如果你够味,那我无话可说!回正题,简单的讲我们对数据的操作都是通过该对象进行的,它包含了CRUD以及其他操作的方法。那么我们该如何去获取呢?可以使用方法getCurrentSession() 以及 openSession()。接下来分别介绍这两个方法:
1. getCurrentSession()
首先可以尝试理解下这个方法的字面意思:获取当前的Session,这个当前的指的就是当前线程啦。在Session上下文配置为Thread的时候,这个方法会在Session上下文里面寻找并返回当前线程中已经创建但是事务还未提交或回滚时所用的Session对象,但是如果当前线程的事务已经提交/回滚,那么该对象也会从Session上下文移除。后续再次调用该方法,那么就会创建新的Session对象返回。通过这种方法获取的Session对象在事务提交或回滚之后会自动释放, 此时再次调用close将导致错误。而另外这个所谓的Session上下文就是我们在核心配置文件里面所配置的属性:
<property name="current_session_context_class">thread</property>
可以使用下面的代码测试关于使用getCurrentSession()方法获取的Session是否为同一对象:
static SessionFactory sessionFactory = null;
@Test
public void test1(){
sessionFactory = HibernateUtils.getSessionFactory();
Session session1 = sessionFactory.getCurrentSession();
session1.beginTransaction();
/*
* 不要忘记在核心配置文件配置current_session_context_class选项!
* 在还未进行提交,回滚的情况下(注释该条语句),使用getCurrentSession得到的对象始终是同一个
* 但是当提session1提交之后(不再注释该条语句),再次在该线程获取Session对象,就是新的了
* */
//session1.getTransaction().commit();
Session session2 = sessionFactory.getCurrentSession();
System.out.println(session1==session2);
}
@AfterClass
public static void endTest(){
sessionFactory.close();
}
2.openSession()
每次调用都是获取一个新的Session对象绑定到当前线程进行后续的操作。并且在完成之后我们需要调用close()将其释放
4.Transaction
与学习JDBC时候的事务所具有的功能类似。对一个操作进行提交或回滚(暂时未了解更多),Session对象的操作更像是在操作实体类,而使用这个对象才是真正的将我们对实体类的操作进行持久化(提交)或放弃更改(rollback),这样的话在提交之前都是针对实体类进行操作的,所以无论出现什么样的异常,至少此时的数据库是不受影响的。而我们在进行一次正常的操作之后,真正持久化的过程由Hibernate来帮我们完成。而在进行查询的操作时候,就可以选择不再使用事务,因为查询不是对数据库进行修改而是获取数据,不存在对数据库的更改。
暂时总结了这么多,后续如有可能会继续补充