hibernate入门(加载策略、管理对象、一级缓存及快照)
加载策略
指hibernate查询数据时,采用什么样的方式将数据写入内存。Hibernate中提供了两种方式来加载数据:懒加载和即时加载。
懒加载:懒加载又称延迟加载,指使用hiberante API查询数据时,不会立即将数据写入内存。而是等到真正使用数据时才会发出sql语句,到数据中查询数据。
即时加载:指使用hibernate API查询数据时,会立即发出sql语句,查询数据。并将数据写入内存。
就例如你在打游戏,朋友让你去帮个忙,你说等一下再去,就不是必须立即执行的,可以理解为延迟加载,而在真的必须去执行的比如说上课了,你必须停止你的游戏去上课,就是即时加载。
而hibernate有一个工具类,将通用的部分构成的
package com.liuchunming.util;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class SessionFactoryUtils {
private static final String HIBERNATE_CONFIG_FILE = "hibernate.cfg.xml";
private static ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
// 创建数据库的会话工厂
private static SessionFactory sessionFactory;
// 读取hibernate核心配置
private static Configuration configuration;
static {
try {
configuration = new Configuration();
configuration.configure(HIBERNATE_CONFIG_FILE);
// 创建Session会话工厂
sessionFactory = configuration.buildSessionFactory();
} catch (Exception e) {
e.printStackTrace();
}
}
public static Session openSession() {
Session session = threadLocal.get();
if (null == session) {
session = sessionFactory.openSession();
threadLocal.set(session);
}
return session;
}
public static void closeSession() {
Session session = threadLocal.get();
if (null != session) {
if (session.isOpen())
session.close();
threadLocal.set(null);
}
}
public static void main(String[] args) {
Session session = SessionFactoryUtils.openSession();
System.out.println("Session状态:" + session.isOpen());
System.out.println("Session会话已打开");
SessionFactoryUtils.closeSession();
System.out.println("Session会话已关闭");
}
}
load 懒加载/延迟加载示例
懒加载的支持关键字是load
在使用我们的懒加载时,我们如果找不到结果,会出现ObjectNotFoundException
异常,如下代码:
package com.liuchunming.test;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.liuchunming.entity.User;
import com.liuchunming.util.SessionFactoryUtils;
public class Demo2 {
public void users() {
//获取session
Session session = SessionFactoryUtils.openSession();
//开启事务
Transaction ts= session.beginTransaction();
User user=new User();
user.setId(3);
User user2 = session.load(User.class, user.getId());
//提交事务
ts.commit();
//释放资源
session.close();
System.out.println(user2);
}
public static void main(String[] args) {
Demo2 d=new Demo2();
d.users();
}
}
为什么报错?
因为懒加载是在用的时候去调用SQL语句查询,而在我输出的位置前我已经将session关闭,就会导致报错。将关闭session放在输出语句后面就 不会报错啦!
get 立即加载示例
如果get获取不到值的话,结果为null
package com.liuchunming.test;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.liuchunming.entity.User;
import com.liuchunming.util.SessionFactoryUtils;
public class Demo2 {
public void users() {
//获取session
Session session = SessionFactoryUtils.openSession();
//开启事务
Transaction ts= session.beginTransaction();
User user=new User();
user.setId(6666);
User user2 = session.get(User.class, user.getId());
//提交事务
ts.commit();
//释放资源
session.close();
System.out.println(user2);
}
public static void main(String[] args) {
Demo2 d=new Demo2();
d.users();
}
}
结果:
代理对象
这里的代理对象指的是我们缓存在session当中的对象,我们所使用的的取的对象都是缓存在session当中的代理对象。
hibernate管理对象的三种状态
流程图
hibernate管理对象的三种状态:临时状态、持久状态、游离状态。
临时状态:例如你在店里与老板进行交流就处于临时状态。
持久状态:例如你和小学同学一直到现在关系都挺好的就处于持久状态。
游离状态:例如你和小学同学当初关系挺好的但是很久不联系了就处于游离状态。
解释:当使用构造函数new一个对象并加载到session后的时候会进入临时状态,当session加载了这个Javabean并进行save操作后会进入持久状态,在持久的状态把session进行close后或者提交事务后会进入游离状态,如果游离状态想进入到持久状态就要进行更新的操作。
hibernate管理对象的三种状态,实际上是hibernate对对象的操作在哪个地方。
一级缓存及快照
一级缓存:我们保存在session当中的数据其实就是缓存在session当中的,当session关闭时就会清空缓存。
为什么需要缓存?
提高性能,减少访问数据库次数。
快照:当我们查询数据的时候,查询的数据会保存到session当中并进入持久状态,其实也相当于副本,当数据放在session当中的时候,别人对数据库中的数据进行了更新,对我们是没有影响的,因为我们拿到的是更新前的数据,相当于给数据拍了个照片。
当hibernate查询对象的的时候,就是在一级缓存当中查询的,如果差不多,就会去数据库当中进行查询再更新到session当中,相当于一次快照。
hibernate中知道那些数据被更新和没被更新当你访问的数据在数据库中没被更新的时候是直接访问缓存中的数据,相当于少了一次访问数据库的过程让效率更高了,当你访问的数据被更新了它会去查询数据库中的数据到快照中。