Hibernate5的Session接口浅析

Session接口的基础知识
Session接口时Hibernate5中的核心接口,Session对象是Hibernate5技术的核心,持久化对象的生命周期、事务的管理及持久化对象的增加、修改和删除都是通过Session对象来完成的。Hibernate5在操作数据库之前必须先取得Session对象。
Session对象不是线程安全的,一个Session对象最好只由一个单一线程来使用。同时该对象的生命周期要比SessionFactory短,其生命通常在完成数据库中一个短暂的系列操作之后结束。一个应用系统中可以自始自终只有一个SessionFactory对象。Session对象通过SessionFactory对象的getCurrentSession()或者openSession()方法获取,代码如下:

Configuration cfg=new Configuration().configure("hibernate.cfg.xml");
SessionFactory sf=cfg.buildSessionFactory();
Session session=sf.openSession()

获取Session对象后,Hibernate5内部并不会立即获取操作数据库的java.sql.Connection对象,而是等待Session对象真正需要对数据库进行增、删、改、查等操作时,才会从数据库连接池中的获取Connection对象。

Session类在定义上与普通的JavaBean类没有区别,但他也有独特的方法,其方法按用途可分为以下5类:

  1. 获取持续化对象:get()和load()等方法。
  2. 持久化对象的保存、更新和删除:save()、update()、saveOrUpdate()和delete()等方法。
  3. createQuery()方法:用来从Session生成Query对象。
  4. beginTransaction()方法:用来从Session生成Transaction对象。
  5. 管理Session的方法:isOpen()、flush()、clear()、evict()和close()等方法。其中isOpen()方法用来检查Session是否仍然打开;flush()方法用来清理Session缓存,并把缓存中的SQL语句发送出去;clear()方法用来清除Session中的所有缓存对象;evict()方法用于清除Session缓存中的某个对象;close()方法用来关闭Session。

通过方法获取持久化对象
获取持久化对象的方法只要有两种:get()方法和load()方法,它们都是通过主键id来获取持久化对象的。

1、使用get()方法获取持久化对象
例如:

public Object get(Class className,Serializable id)

className是类名,id是对象的主键,如果id的类型是int,可通过new Integer(id)的方法生成一个Integer对象。
以下代码是获取一个主键id为66的UserInfoPO对象:

UserInfoPO ui=(UserInfoPO)session.get(UserInfoPO.class,new Integer(66));

get()方法获取持久化对象时的执行过程如下:

  1. 通过id在Session缓存中查找对象,如果存在与id主键-值对应的对象,直接将其返回;
  2. 如果在Session缓存中没有查询到对应的对象,则在二级缓存中查找,找到后将其返回;
  3. 如果在前两个步骤的操作中都没有找到该对象,则从数据库中加载拥有此id的对象;

从上面步骤可以看出,get()方法并不总是发送SQL语句查询数据库,只有缓存中无此数据时,才向数据库发送SQL语句获取数据。

2、使用load()方法获取持久化对象
基本作用和get()方法差不多,其主要区别如下:
(1)、当立即加载PO时,如果对象存在,get()方法和load()方法没有区别,他们都可以取得已初始化的对象;但当对象不存在且是立即加载时,get()方法返回null,而load()方法则弹出一个异常。因此使用load()方法时,要确认查询的主键id一定是存在的。
(2)、当延迟加载对象时,get()方法仍然使用立即加载的方式发送SQL语句,并得到已初始化的对象,而load()方法则根本不发送SQL语句,它返回一个代理对象,这个对象直接被访问使用时才被初始化。

操作持久化对象的常用方法
1、使用save()方法操作持久化对象
使用save()方法可将一个持久化对象的属性取出放入PreparedStatement(具有预编译功能的SQL类)语句中,然后向数据库表中插入一条记录。下面的代码把一个新建UserInfoPO对象持久化到数据库中,即把一条记录插入到数据库中。

UserInfoPO ui=new UserInfoPO();       
ui.setID(66);									//为对象设定一个id值
Session session=sf.openSession();				//打开Session
Transaction tx=session.beginTransaction();  	//开启事务
session.save(ui);								//调用save()方法保存数据
tx.commit();									//提交事务
session.close();								//关闭Sessioon

当Session保存一个持久化对象时,按照如下步骤进行操作
(1)、根据映射文件中的配置为主键id设置生成算法,为info指定一个id。
(2)、将UserInfoPO对象存入Session对象的内部缓存中。
(3)、当事务提交时,清理Session对象缓存中的数据,并将新对象通过Hibernate5框架生成的insert into语句持久化到数据库中。

在调用save()方法时,并不立即执行SQL语句,而是等到清理完缓存后在执行。如果在调用save()方法后又修改了UserInfoPO的属性,则Hibernate5框架将会发送一条insert into语句和一条update语句来完成持久化操作。

UserInfoPO ui=new UserInfoPO();       
ui.setID(66);									//为对象设定一个id值
ui.setUserName("李想一");						//设定用户名的值
Session session=sf.openSession();				//打开Session
Transaction tx=session.beginTransaction();  	//开启事务
session.save(ui);								//调用save()方法保存数据
ui.setUserName("李想二");						//设定用户名的值
tx.commit();									//提交事务
session.close();								//关闭Sessioon

因此,最好是在对象状态稳定(即属性不再发生变化)时在调用save()方法,这样可以少执行一条update语句。

2、使用update()方法操作持久化对象
Session的update()方法可以用来更新脱管对象到持久化对象。

UserInfoPO ui=new UserInfoPO();       
Session session=sf.openSession();				//打开Session
Transaction tx=session.beginTransaction();  	//开启事务
ui=(UserInfoPO)session.get(UserInfo.class,new Integer(66));
ui.setUserName("李想");
session.update(ui);								//更新脱管对象
tx.commit();									//提交事务
session.close();								//关闭Sessioon

使用update()方法时,HIbernate5框架并不会立即发送SQL语句,而是将对象的更新操作积累起来,在事务提交时由flush()清理缓存,并发送一条SQL语句完成全部更新操作。

3、使用saveOrUpdate()方法操作持久化对象
对脱管对象使用save()方法是不对的,对临时对象使用update()方法也是不对的,所以为了解决这个问题,便产生了saveOrUpdate()方法。

UserInfoPO ui=new UserInfoPO(); 
ui.setId(66);      
Session session=sf.openSession();				//打开Session
Transaction tx=session.beginTransaction();  	//开启事务
ui=(UserInfoPO)session.get(UserInfo.class,new Integer(66));
session.saveOrUpdate(ui);						//使用方法保存数据
tx.commit();									//提交事务
session.close();								//关闭Sessioon

4、使用delete()方法操作持久化对象
Sessiondedelete()方法负责删除一个对象(包括持久化对象和脱管对象)。

UserInfoPO ui=new UserInfoPO();       
Session session=sf.openSession();				//打开Session
Transaction tx=session.beginTransaction();  	//开启事务
ui=(UserInfoPO)session.get(UserInfo.class,new Integer(66));
session.delete(ui);								//删除持久化对象
tx.commit();									//提交事务
session.close();								//关闭Sessioon

使用delete()方法删除对象时,会出现一些性能上的问题。例如从以上代码中可以看出,当删除一个对象时,先调用get()方法加载这个对象,然后调用delete()方法删除对象,但此过程发送了一条select和delete语句。实际上select语句是不必要的,这种情况在批量删除时尤为明显。为了解决批量删除时产生的性能问题,常用的方法是使用批量删除操作。

UserInfoPO ui=new UserInfoPO();       
Session session=sf.openSession();				//打开Session
Transaction tx=session.beginTransaction();  	//开启事务
Query q=session.createQuery("delete from UserInfoPO");  //使用HQL语句进行删除
q.executeUpdate();								//删除对象
tx.commit();									//提交事务
session.close();								//关闭Sessioon
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值