您的位置:首页 > 其它

Hibernate教程之三:Session对象核心方法

2018-03-28 10:34 639 查看

一、Session接口

Session 是应用程序与数据库之间交互操作的一个单线程对象,是 Hibernate 运作的中心,所有持久化对象必须在 session 的管理下才可以进行持久化操作。此对象的生命周期很短。Session 对象有一个一级缓存,显式执行 flush 之前,所有的持久层操作的数据都缓存在 session 对象处。相当于 JDBC 中的 Connection

Session 类的方法:

作用方法
取得持久化对象的方法get()、load()
持久化对象保存save()、persist()、saveOrUpdate()
持久化对象更新update()、saveOrUpdate()
持久化对象删除delete()

Hibernate中对象状态转换图



状态解释
临时对象(Transient)无OID、不在session缓存中、数据库中没有对应的记录
持久化对象(Persist)有OID、在session缓存中、数据库有对应的记录、flush 缓存后数据库表与对象属性同步改变
删除对象(Removed)有OID、不在session缓存、数据库中没有和它对应的数据
游离对象(Detached)有OID、不在session缓存、数据库中可能有和它对应的数据
我们这么去解释:

对象的状态是有一个参照物的,每一个对象参照的就是数据库中的每一行数据(通过OID唯一识别,也就是数据库表中的主键)。

OID和主键的关系:OID针对的是一个实在的对象,主键是数据库概念

下面我们具体讲解下这些方法的区别及用法

二、get()、load()方法的区别

场景get方法load方法
查询一个对象立即加载延迟加载
session被关闭任然获得对象:Session was already closed异常LazyInitializationException 异常
数据库中没有该记录;session没有被关闭null异常could not initialize proxy
延迟加载(本质是动态代理):查询只返回代理对象,只有用到了具体的属性才由代理对象去发送查询的sql

@Test
public void get() {
User user=(User) session.get(User.class, 170618);
session.close();
System.out.println("user:"+user);
}

@Test
public void load() {
User user=(User)session.load(User.class, 170618);
session.close();
System.out.println("user:"+user);
}


三、save()和persist()方法的区别

作用save()方法persist()方法
游离态转持久态
为对象分配ID
在Flush时会发送对应的sql
预设OID无效,可插入无效,抛异常,不可插入
方法后设置ID将抛出异常
@Test
public void save() {
User user=new User();
user.setId(23);//无效的
user.setName("miemei");
user.setTelPhone("857412369");
System.out.println("user:"+user);

session.save(user);
System.out.println("user:"+user);
//将报异常:user.setId(23);
}

@Test
public void persist() {
User user=new User();
user.setId(23);//无效的
user.setName("ccccc");
user.setTelPhone("0987654");
System.out.println("user:"+user);

session.persist(user);
}


四、refresh()和flush()、commit()方法区别

方法功能
flush()方法刷新全部对象、针对所有在session缓存中的持久态对象发送SQL(本质是执行了SQL
refresh()方法会强制发送 SELECT 语句, 以使 Session 缓存中对象的状态和数据表中对应的记录保持一致!
commit()方法这个方法的本质是提交已经执行的SQL操作、但是调用前会隐式调用flush()操作
*flush是使数据库表中的对象与session缓存的一致(发送UPDATE)

refresh是使session缓存中对象和数据库表中的一致(发送SELECT)

@Test
public void TestFlush() {
//查询:发送一条语句
User user1=(User) session.get(User.class,170618);
//这时没发送sql:更改session内存中对象的属性值,但不更改数据库(也就是不发送sql)
user1.
4000
setName("pangpang");
//现在发送sql了,控制台可以看到了(但是没有提交事务)
session.flush();

}

@Test
public void TestRefresh() {
//session级缓存
User user1=(User) session.get(User.class,170618);
System.out.println("user1:"+user1);
//刷新指定的对象:user1
session.refresh(user1);
System.out.println("user1:"+user1);
}


五、update()方法

功能解释
更新持久化对象不需要显示的调用 update 方法. 因为在调用 Transaction 的 commit() 方法时, 会先执行 session 的 flush 方法
更新游离态对象需要显式的调用 session 的 update 方法. 可以把一个游离对象变为持久化对象
OID为空、数据库记录没有对应的主键ID调用session的update将抛出异常
session缓存中有多个OID相同的对象对其中一个对象执行session的update操作抛出异常
*update方法执行前:根据对象的OID去数据中查找对应的主键ID,当没有查到时,无法更新(抛出异常)。当查到的时候呀才发送更新语句。

@Test
public void testUpdate() {
User user1=(User) session.get(User.class,170618);
System.out.println("user1:"+user1);

transaction.commit();
session.close();

session = sessionFactory.openSession();
transaction = session.beginTransaction();

//此时,user1对象已经相对于session对象为游离态,需要显示调用update
user1.setName("胖胖");
session.update(user1);
}


六、saveOrUpdate()方法

OID为空:执行save语句

OID不为空:执行update方法,当数据库表中没有对应的OID将报异常

也可这么说:临时态对象执行save方法,游离态对象执行update方法

@Test
public void testSaveOrUpdate() {
User user=new User();
//user.setId(1);
user.setName("weipang");
user.setTelPhone("125874");
session.saveOrUpdate(user);
}


七、delete()方法

先根据OID查找数据库

有匹配,执行删除

无匹配,抛异常

@Test
public void testDelete() {
User user=(User) session.get(User.class,170618);
session.delete(user);
System.out.println("user:"+user);
}


八、eviet()方法和clear()、close()方法

方法功能
eviet()将session缓存中的指定对象从持久态变成游离态
clear()将session缓存中所有的对象从持久态变成游离态
close()关闭session,持久态变为游离态
@Test
public void testEvict() {
User user=(User) session.get(User.class,170678);
session.evict(user);
user.setName("好胖呀");
}

@Test
public void testClear() {
User user=(User) session.get(User.class,170678);
User user1=(User) session.get(User.class,170639);
session.clear();
System.out.println("user:"+user);
System.out.println("user1:"+user1);
user.setName("好胖呀");
}

@Test
public void testClose() {
User user=(User) session.get(User.class,170678);
User user1=(User) session.get(User.class,170639);
session.close();
System.out.println("user:"+user);
System.out.println("user1:"+user1);
user.setName("好胖呀");
}


九、doWork()方法

这个本质就是获得JDBC原生的对象connection对象

@Test
public void testDoWork(){
//本质是一个匿名内部类
session.doWork(new Work() {
@Override
public void execute(Connection connection) throws SQLException {
System.out.println(connection);
//调用存储过程.
}
});
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐