Hibernate的核心类讲解1(第二天)

今天来介绍一下Hibernate的核心类


我之前写过有关Hibernate的crud操作,简单入门过后我们能总结出来,Hibernate有四个核心类是我们做基本的增删改查所不可缺少的:Configuration,SessionFactory,Session,Transation.

1.Configuration:

这个类用于读取hibernate.cfg.xml配置文件,从而加载数据库驱动等等信息,管理*.hbm.xml映射文件。

使用方法: Configuration config = new Configuration().configure();

打开源码我们能看到configure方法有几种重载,其中一种默认了配置文件

public Configuration configure() throws HibernateException {
		configure( "/hibernate.cfg.xml" );
		return this;
	}

还有一种是能够自己指定名字和路径的

public Configuration configure(String resource) throws HibernateException {
		log.info( "configuring from resource: " + resource );
		InputStream stream = getConfigurationInputStream( resource );
		return doConfigure( stream, resource );
	}
在早先版本的Hibernate中还支持属性文件.propertues的配置,这个配置文件在我们下载的hibernate包中能找到 /project/etc下就有,当我们对hibernate.cfg.zml的配置有疑惑的时候可以查看一下这个属性文件怎么配置。

当然自己指定文件也行啊URL也行等等,原理是一样的我就不写了。

注意Configuration由于是一个读取文件的操作,因此我们通常只需要在整个程序中,创建一个Configuration实例就够了(每次操作数据库都读文件很吃内存)。


2.SessionFactory:

SessionFactory(接口)要在Configuration读取到配置文件加载驱动完以后才能创建。
作用和注意:
1.缓存sql语句和某些数据
(后面还会提到)
2.某个应用访问多个数据库的时候则要建立多个回话工厂实例。
3.该实现类对象比较吃内存,一般在单例模式下使用(保证一个数据库一个SessionFactory)。

这个类作用就是创建Session,从名字也能看出采用了工厂模式。关于这个接口还是要结合Session接口来说的。


3.Session:

这个类相对复杂了,我们从这个类的创建和使用两点来说明

首先创建这个类其实有两种方法,前面的博客我只是用了最好理解的一个方法,现在来说说这两个方法,明晰一下session这两个方法的本质。

1.session = sessionfactory.openSession()  2.session = sessionfactory.getCurrentSession()

异同点:

1.同样都是创建session,前者每次获取的是一个全新的session,而后者则是获取的当前线程所绑定的的session(也就是说在同一个线程中获取的session对象是同一 个),而事务是在一个线程下的,也就能保证获取到当前事务的session。在有些情况来说是有利的。

2.用getCurrentSession()方法则需要在hibernate.cfg.xml中配置 <property name="current_session_context_class">thread</property> 意思是线程绑定。

3.后者触发异常,手动回滚的同时就能把session关闭,前者不能(但还是建议大家用在finally里面还是要判断session的isOpen方法和是否为空的方法,这么做保险)。

4.后者要查询的话,也需要事务机制,而前者则只在出现对数据库发生修改的时候需要事务。

如何选取:因为session是不同步的,如果需要在一个线程中需要用同一个Session那就用后者(Session线程不同步),比如不同的Service都要用同一个Session的时候。而只在一个Service使用Session的时候用前者。如果项目涉及到多个数据库的使用,也要用后者,保证事务的完整性。

这里说一下JTA的概念,有的时候使用getCurrentSession的使用者会给current_session_context_class的属性内设置为 jta ,而不是thread.jta是全局事务,thread是本地事务。
局部事务和全局事务:
一个程序假设只涉及一个数据库,这个时候的事务就是局部事务。操作多个数据库的涉及的事务则是全局事务。
想切换全局事务和局部事务只需要修改<property name="current_session_context_class">jta</property> 即可。


有关session还有一个要说的就是load和get方法,这两个方法都是用来读取数据库的,但是用法和实质上还是有很大差别的。

load具有“懒加载”机制,因为当我们用load查询数据库时,load首先会查看缓存中(分别在查看一级缓存和二级缓存,一级缓存也就是上面提到的SessionFactory这个接口充当的作用,二级缓存是介于磁盘和内存中的)是否有我们要的数据,如果有直接返回实体对象,没有则会创建一个 实体代理对象 ,这里注意是一个代理对象,当我们要使用这个实体代理对象(在程序员的眼中其实就是一个Employee对象)的时候再去数据库查询,如果查询到则返回一个实体对象并在缓存存入信息,查询不到则抛出ObjectNotFoundException.

get不具备懒加载机制,get也是在查询的时候先去缓存里面查找,如果找到了就返回实体类对象,找不到则立马去数据库找,找到了并在缓存存入信息,找不到返回null.

以上比较可以看出,实际上我们在调用load方法的时候(缓存中)是不会发出SQL查询语句的,只有在使用返回值的时候才会发出SQL语句;get相反,如果缓存中没有信息的时候就立马发出一条SQL语句。

Employee employee = (Employee) session.load(Employee.class, 1);
单纯这样控制台没有SQL语句
Employee employee = (Employee) session.load(Employee.class, 1);
			System.out.println(employee.getEmail());

当我们试图使用其返回值的时候,可以在控制台看到一条SQL语句

Employee employee1 = (Employee) session.get(Employee.class, 1);
			System.out.println(employee1.getEmail());
get方法则会立马加载数据库的数据,不会等使用返回值。而上面这段代码同样也只打印一条SQL语句,原因是在数据库查询完以后会在缓存存入这个id为1的employee,当我们使用这个对象的时候就直接从缓存获得,而无需去数据库找。

当然我们也可以取消懒加载,只要在Xxx.hbm.xml文件中你要指定的取消懒加载的那个类class标签上设置 lazy="false" 属性即可。这时用load方法就会和get一样。

稍微提一下缓存的概念.

一级缓存:实际上是SessionFactory(前面提到过),也叫Session级缓存。
二级缓存:介于内存和磁盘之间,所以二级缓存既可以在内存中也可以在配置在文件中。二级缓存只有你配置了才能使用,但一级缓存是肯定要用的。
所以在懒加载过程中,如果一级二级缓存都没有要找的信息,才回去数据库找;找到后还会在两个缓存中添加进去数据,下次找的时候就快了。

懒加载从某种意义上来说是对查询业务的优化,缓存机制就是为了减少数据库的负载(减少对数据库的操作),在数据库负载能力较差的时候是个很好的优化策略


4.Transaction:

数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行.

因此在执行对数据库进行修改的操作时,必须要创建并提交事务,如果出现异常一定要回滚,否则不能保证数据的完整性。

对于事务还有要讲的就是我们一定要注意给事务添加回滚,防止出现异常后事务不完整。


有关hibernate其他的类或接口的讲解将在其他博客中说明。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值