这篇博客可能有点偏向于理论,博主尽量结合代码和举例来体现
Hibernate管理对象的三种状态
首先来看图:
临时状态:
当实体对象被new新建时,对象状态为临时状态,此时与session无任何联系,可以使用save方法进行保存到数据库,转为持久状态
Goods goods=new Goods("哇哈哈",11.0f,"饮料");
游离状态:
session关闭会成为游离状态,session缓存中不存在该对象,但数据库中有这条记录,可以通过update进行数据更新,让对象变为持久状态
持久状态:
当对象被session进行
get
或者save
时,对象状态为持久状态,持久化存入数据库,如果session工厂会话关闭,对象成为游离状态。当使用delete方法删除时加上commit的事务提交,对象在数据库中不会存在,而在缓存中也不会保留数据,此时对象重新成为临时状态
package com.xiaoyang.test;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import com.xiaoyang.entity.Goods;
public class Demo {
public static void main(String[] args) {
//使用hibernate核心类
Configuration cfg=new Configuration().configure("hibernate.cfg.xml");
//创建核心api中的session工厂
SessionFactory buildSessionFactory = cfg.buildSessionFactory();
//获取工厂中的session会话
Session session = buildSessionFactory.openSession();
//开启事务
Transaction ts = session.beginTransaction();
Goods goods = session.get(Goods.class,5);
session.close();
session.clear();
System.out.println(goods);
}
}
一级缓存和快照
hibernate向一级缓存放入数据时,同时保存快照数据
上面的快照数据就是goods的属性,一级缓存就是goods对象引用,而快照会将对象属性值封装保存在快照区域,而book的引用可以修改属性值,在commit提交时,如果一级缓存和快照数据不一致,则会发送update进行数据修改
可以看到即使session被关闭,输出的值也是一致的,因为在这时候输出的值是goods对象值,也就是一级缓存中的数据
但是clear+close就会将缓存清除,就会报错session已关闭:
如果是使用save方法保存对象,使用commit方法提交后,hibernate也会清除缓存.
加载策略
立即加载、延时加载
立即加载也就是get()方法,立即加载每次都会去数据库查找
延迟加载(load),查询是不会立即访问数据库,而是返回代理对象,只有真正需要使用对象的时候才会访问数据库,个人认为延时加载会比立即加载性能好。
但是需要注意的一点,延时加载和session是否关闭有关系,因为延时加载在被调用时才会去执行,如果此时session关闭,那么就会报错,例如:
package com.xiaoyang.test;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import com.xiaoyang.entity.Goods;
public class Demo {
public static void main(String[] args) {
//使用hibernate核心类
Configuration cfg=new Configuration().configure("hibernate.cfg.xml");
//创建核心api中的session工厂
SessionFactory buildSessionFactory = cfg.buildSessionFactory();
//获取工厂中的session会话
Session session = buildSessionFactory.openSession();
//开启事务
Transaction ts = session.beginTransaction();
Goods goods = session.load(Goods.class, 5);
session.close();
System.out.println(goods);
}
}
这篇博文到这就结束了,get方法立即加载就不赘述了,上面已经写过,有问题可以评论区指出,欢迎交流…