首页 技术 正文
技术 2022年11月14日
0 收藏 477 点赞 4,725 浏览 19582 个字

首先我们应该弄清什么是hibernate缓存:hibernate缓存是指为了降低应用程序对物理数据源的访问频次,从而提高应用程序的运行性能的一种策略。我们要将这个跟计算机内存或者cpu的缓存区分开。

一、hibernate查询的几种方式

既然是基于查询分析hibernate一级缓存,我们就来分析分析hibernate查询方式

1、通过session对象的get()方法

我们通过查看hibernate的api文档找到了session接口,并重点看了get()方法,我们主要使用一下两种get()方法:
Hibernate一级缓存(基于查询分析)

通过传入由实体类获得的Class类对象(姑且叫做类类型)和该类的唯一标识符两个参数,返回一个Object类型的查询对象。

Hibernate一级缓存(基于查询分析)

通过传入实体类名和该类对象的唯一标识符两个参数,返回一个Object类型的查询对象。

代码示例:

 package com.third; import java.util.List; import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test; import com.third.Dao2.Students2;
import com.third.Dao2.Students2PartInfo; public class Test3 {
private static SessionFactory sessionFactory;
private static Session session;
private static Transaction transaction;
@Before
public void init(){
//先获取配置对象,匹配hibernate.cfg.xml文件
Configuration config=new Configuration().configure();
//获取注册服务对象(该对象中包含hibernate.cfg.xml中的<properties>和<maping>信息
ServiceRegistry serviceRegistry=new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry();
//获取sessionFactory对象,通过sessionFactory对象读取hibernate.cfg.xml文档信息,并通过<mapping>标签加载hbm.xml文件信息
sessionFactory=config.buildSessionFactory(serviceRegistry);
} @Test
public void test3(){
//通过sessionFactory对象获取session对象
session=sessionFactory.openSession();
//通过session对象开启事务,并且返回事务(transaction)对象
transaction=session.beginTransaction(); //第一个session对象通过get()方法第一次查询相同记录
Students2 stu1=(Students2) session.get(Students2.class, 1);
//第一个session对象通过get()函数第二次查询相同记录
Students2 stu2=(Students2) session.get(Students2.class, 1);
System.out.println("学号:"+stu1.getSid()
+" 姓别:"+stu1.getSgender()+" 姓名:"+stu1.getSname());
System.out.println("学号:"+stu2.getSid()
+" 姓别:"+stu2.getSgender()+" 姓名:"+stu2.getSname()); //重新获得一个session对象,再一次执行session对象的get()方法查询相同记录
Session session1=sessionFactory.openSession();
Students2 stu3=(Students2) session1.get(Students2.class, 1);
System.out.println("学号:"+stu3.getSid()
+" 姓别:"+stu3.getSgender()+" 姓名:"+stu3.getSname()); } @After
public void destory(){
transaction.commit();
//关闭开启的资源
if(session!=null){
session.close();
}
if(sessionFactory!=null){
sessionFactory.close();
}
}
}

运行结果:

Hibernate:
select
students2x0_.SID as SID1_1_0_,
students2x0_.SNAME as SNAME2_1_0_,
students2x0_.SGENDER as SGENDER3_1_0_
from
STUDENTS2 students2x0_
where
students2x0_.SID=?
学号:1 姓别:女 姓名:小美
学号:1 姓别:女 姓名:小美
Hibernate:
select
students2x0_.SID as SID1_1_0_,
students2x0_.SNAME as SNAME2_1_0_,
students2x0_.SGENDER as SGENDER3_1_0_
from
STUDENTS2 students2x0_
where
students2x0_.SID=?
学号:1 姓别:女 姓名:小美

分析:在同一个session对象的条件下查询同一表格记录,hibernate解析的SQL语句只会执行一次,重新获得一个session对象后,再去查询相同的表格记录时,hibernate解析而成的SQL语句会在执行一次。

我们不难得出:在同一个session对象的情况下,使用get()方法查询相同的对象会使用到缓存(一级缓存),不同的session对象在查询相同对象正常情况下是不会使用缓存。

Hibernate一级缓存(基于查询分析)

2、通过session的load()方法

我们通过查看hibernate的api文档找到了session接口,并重点看了load()方法,我们主要使用一下两种load()方法:

Hibernate一级缓存(基于查询分析)

通过传入由实体类获得的Class类对象(姑且叫做类类型)和该类的唯一标识符两个参数,返回一个Object类型的查询对象。

Hibernate一级缓存(基于查询分析)

通过传入实体类名和该类对象的唯一标识符两个参数,返回一个Object类型的查询对象。

代码示例:

 package com.third; import java.util.List; import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test; import com.third.Dao2.Students2;
import com.third.Dao2.Students2PartInfo; public class Test3 {
private static SessionFactory sessionFactory;
private static Session session;
private static Transaction transaction;
@Before
public void init(){
//先获取配置对象,匹配hibernate.cfg.xml文件
Configuration config=new Configuration().configure();
//获取注册服务对象(该对象中包含hibernate.cfg.xml中的<properties>和<maping>信息
ServiceRegistry serviceRegistry=new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry();
//获取sessionFactory对象,通过sessionFactory对象读取hibernate.cfg.xml文档信息,并通过<mapping>标签加载hbm.xml文件信息
sessionFactory=config.buildSessionFactory(serviceRegistry);
} @Test
public void test3(){
//通过sessionFactory对象获取session对象
session=sessionFactory.openSession();
//通过session对象开启事务,并且返回事务(transaction)对象
transaction=session.beginTransaction(); //第一个session对象通过get()方法第一次查询相同记录
Students2 stu1=(Students2) session.load(Students2.class, 1);
//第一个session对象通过get()函数第二次查询相同记录
Students2 stu2=(Students2) session.load(Students2.class, 1);
System.out.println("学号:"+stu1.getSid()
+" 姓别:"+stu1.getSgender()+" 姓名:"+stu1.getSname());
System.out.println("学号:"+stu2.getSid()
+" 姓别:"+stu2.getSgender()+" 姓名:"+stu2.getSname()); //重新获得一个session对象,再一次执行session对象的get()方法查询相同记录
Session session1=sessionFactory.openSession();
Students2 stu3=(Students2) session1.load(Students2.class, 1);
System.out.println("学号:"+stu3.getSid()
+" 姓别:"+stu3.getSgender()+" 姓名:"+stu3.getSname()); } @After
public void destory(){
transaction.commit();
//关闭开启的资源
if(session!=null){
session.close();
}
if(sessionFactory!=null){
sessionFactory.close();
}
}
}

运行结果:

Hibernate:
select
students2x0_.SID as SID1_1_0_,
students2x0_.SNAME as SNAME2_1_0_,
students2x0_.SGENDER as SGENDER3_1_0_
from
STUDENTS2 students2x0_
where
students2x0_.SID=?
学号:1 姓别:女 姓名:小美
学号:1 姓别:女 姓名:小美
Hibernate:
select
students2x0_.SID as SID1_1_0_,
students2x0_.SNAME as SNAME2_1_0_,
students2x0_.SGENDER as SGENDER3_1_0_
from
STUDENTS2 students2x0_
where
students2x0_.SID=?
学号:1 姓别:女 姓名:小美

分析:在同一个session对象的条件下查询同一表格记录,hibernate解析的SQL语句只会执行一次,重新获得一个session对象后,再去查询相同的表格记录时,hibernate解析而成的SQL语句会在执行一次。

我们不难得出:在同一个session对象的情况下,使用load()方法查询相同的对象会使用到缓存(一级缓存),不同的session对象在查询相同对象正常情况下是不会使用缓存。

我们可以总结得到,load()函数的查询流程和get()函数的查询流程基本相同。

3、通过session对象的createQuery(String HQL)方法

我们通过查看hibernate的api文档找到了session接口,找到createQuery(String HQL)方法,该方法的返回值类型是一个Query(查询),于是,我们找到Query接口,我们找到了两个方法,是将查询结果返回的。

Hibernate一级缓存(基于查询分析)

以List的方式返回查询结果

Hibernate一级缓存(基于查询分析)

以迭代器的方式返回查询结果

(1)以List的方式返回查询结果

1)有select子句

 package com.third; import java.util.List; import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test; import com.third.Dao2.Students2;
import com.third.Dao2.Students2PartInfo; public class Test3 {
private static SessionFactory sessionFactory;
private static Session session;
private static Transaction transaction;
@Before
public void init(){
//先获取配置对象,匹配hibernate.cfg.xml文件
Configuration config=new Configuration().configure();
//获取注册服务对象(该对象中包含hibernate.cfg.xml中的<properties>和<maping>信息
ServiceRegistry serviceRegistry=new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry();
//获取sessionFactory对象,通过sessionFactory对象读取hibernate.cfg.xml文档信息,并通过<mapping>标签加载hbm.xml文件信息
sessionFactory=config.buildSessionFactory(serviceRegistry);
} @Test
public void test3(){
//通过sessionFactory对象获取session对象
session=sessionFactory.openSession();
//通过session对象开启事务,并且返回事务(transaction)对象
transaction=session.beginTransaction(); //创建HQL语句用于后面的查询需要
//查询所有记录的sid和sname信息(hql语句)
String hql=" select sid,sname,sgender from Students2"; //创建多条记录查询对象query1
Query query=session.createQuery(hql); /*
* 相同session对象,相同query对象,查询相同的对象
*/
List<Object[]> list=query.list();
for (Object[] objects : list) {
System.out.println("学号:"+objects[0]+" 姓名:"+objects[1]+" 性别:"+objects[2]);
} List<Object[]> list1=query.list();
for (Object[] objects : list1) {
System.out.println("学号:"+objects[0]+" 姓名:"+objects[1]+" 性别:"+objects[2]);
}
} @After
public void destory(){
transaction.commit();
//关闭开启的资源
if(session!=null){
session.close();
}
if(sessionFactory!=null){
sessionFactory.close();
}
}
}

运行结果:

Hibernate:
select
students2x0_.SID as col_0_0_,
students2x0_.SNAME as col_1_0_,
students2x0_.SGENDER as col_2_0_
from
STUDENTS2 students2x0_
学号:1 姓名:小美 性别:女
学号:2 姓名:小泽 性别:男
学号:3 姓名:小敏 性别:女
Hibernate:
select
students2x0_.SID as col_0_0_,
students2x0_.SNAME as col_1_0_,
students2x0_.SGENDER as col_2_0_
from
STUDENTS2 students2x0_
学号:1 姓名:小美 性别:女
学号:2 姓名:小泽 性别:男
学号:3 姓名:小敏 性别:女

2)没有select子句

 package com.third; import java.awt.event.FocusEvent;
import java.util.Iterator;
import java.util.List; import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test; import com.third.Dao2.Students2;
import com.third.Dao2.Students2PartInfo; public class Test3 {
private static SessionFactory sessionFactory;
private static Session session;
private static Transaction transaction;
@Before
public void init(){
//先获取配置对象,匹配hibernate.cfg.xml文件
Configuration config=new Configuration().configure();
//获取注册服务对象(该对象中包含hibernate.cfg.xml中的<properties>和<maping>信息
ServiceRegistry serviceRegistry=new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry();
//获取sessionFactory对象,通过sessionFactory对象读取hibernate.cfg.xml文档信息,并通过<mapping>标签加载hbm.xml文件信息
sessionFactory=config.buildSessionFactory(serviceRegistry);
} @Test
public void test3(){
//通过sessionFactory对象获取session对象
session=sessionFactory.openSession();
//通过session对象开启事务,并且返回事务(transaction)对象
transaction=session.beginTransaction(); String hql="from Students2";
Query query=session.createQuery(hql);
List<Students2> stu=query.list();
for (Students2 stu1 : stu) {
System.out.println("学号:"+stu1.getSid()+" 姓名:"+stu1.getSname()+" 性别:"+stu1.getSgender());
}
List<Students2> stu2=query.list();
for (Students2 stu3 : stu2) {
System.out.println("学号:"+stu3.getSid()+" 姓名:"+stu3.getSname()+" 性别:"+stu3.getSgender());
} } @After
public void destory(){
transaction.commit();
//关闭开启的资源
if(session!=null){
session.close();
}
if(sessionFactory!=null){
sessionFactory.close();
}
}
}

运行结果:

Hibernate:
select
students2x0_.SID as SID1_1_,
students2x0_.SNAME as SNAME2_1_,
students2x0_.SGENDER as SGENDER3_1_
from
STUDENTS2 students2x0_
学号:1 姓名:小美 性别:女
学号:2 姓名:小泽 性别:男
学号:3 姓名:小敏 性别:女
Hibernate:
select
students2x0_.SID as SID1_1_,
students2x0_.SNAME as SNAME2_1_,
students2x0_.SGENDER as SGENDER3_1_
from
STUDENTS2 students2x0_
学号:1 姓名:小美 性别:女
学号:2 姓名:小泽 性别:男
学号:3 姓名:小敏 性别:女

分析:相同session,甚至相同query对象情况下,查询相同的对象,hibernate解析的SQL语句在数据库执行了两次。

很明显能看出:session.createQuery(hql).list()方法,不会使用缓存。

Hibernate一级缓存(基于查询分析)

(2)以迭代的方式返回查询结果

代码示例:

 package com.third; import java.util.Iterator;
import java.util.List; import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test; import com.third.Dao2.Students2;
import com.third.Dao2.Students2PartInfo; public class Test3 {
private static SessionFactory sessionFactory;
private static Session session;
private static Transaction transaction;
@Before
public void init(){
//先获取配置对象,匹配hibernate.cfg.xml文件
Configuration config=new Configuration().configure();
//获取注册服务对象(该对象中包含hibernate.cfg.xml中的<properties>和<maping>信息
ServiceRegistry serviceRegistry=new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry();
//获取sessionFactory对象,通过sessionFactory对象读取hibernate.cfg.xml文档信息,并通过<mapping>标签加载hbm.xml文件信息
sessionFactory=config.buildSessionFactory(serviceRegistry);
} @Test
public void test3(){
//通过sessionFactory对象获取session对象
session=sessionFactory.openSession();
//通过session对象开启事务,并且返回事务(transaction)对象
transaction=session.beginTransaction(); /*
* 这里我们执行带有select子句的查询
*/
//创建HQL语句用于后面的查询需要
//查询所有记录的sid和sname信息(hql语句)
String hql=" select sid,sname,sgender from Students2"; //创建多条记录查询对象query1
Query query=session.createQuery(hql);
System.out.println("*************带有select子句的查询*********************");
Iterator it=query.iterate();
while(it.hasNext()){
Object[] obj=(Object[])it.next();
System.out.println("学号:"+obj[0]+" 姓名:"+obj[1]+" 性别:"+obj[2]);
}
//在同一session同一query1对象下查询相同的对象
System.out.println("同一个session并且同一个query对象下查询相同对象:");
Iterator it2=query.iterate();
while(it2.hasNext()){
Object[] obj=(Object[])it2.next();
System.out.println("学号:"+obj[0]+" 姓名:"+obj[1]+" 性别:"+obj[2]);
}
System.out.println("**************不带select子句的查询**********************");
/*
* 这里我们执行不带有select子句的查询
*/
Session session1=sessionFactory.openSession();
String hql1="from Students2";
Query query1=session.createQuery(hql1);
Iterator<Students2> it1=query1.iterate();
while(it1.hasNext()){
Students2 stu=it1.next();
System.out.println("学号:"+stu.getSid()
+" 姓别:"+stu.getSgender()+" 姓名:"+stu.getSname());
}
//在同一session同一query1对象下查询相同的对象
System.out.println("在同一session同一query1对象下查询相同的对象:");
Iterator<Students2> it3=query1.iterate();
while(it3.hasNext()){
Students2 stu=it3.next();
System.out.println("学号:"+stu.getSid()
+" 姓别:"+stu.getSgender()+" 姓名:"+stu.getSname());
}
//在同一个session但是不是一个query对象下查询相同对象
System.out.println("在同一个session但是不是一个query对象下查询相同对象:");
Query query2=session.createQuery(hql1);
Iterator<Students2> it4=query2.iterate();
while(it4.hasNext()){
Students2 stu=it4.next();
System.out.println("学号:"+stu.getSid()
+" 姓别:"+stu.getSgender()+" 姓名:"+stu.getSname());
}
//在不同的session中,查询相同的对象
System.out.println("在不同的session中,查询相同的对象:");
Session session2=sessionFactory.openSession();
String hql2="from Students2";
Query query3=session2.createQuery(hql1);
Iterator<Students2> it5=query3.iterate();
while(it5.hasNext()){
Students2 stu=it5.next();
System.out.println("学号:"+stu.getSid()
+" 姓别:"+stu.getSgender()+" 姓名:"+stu.getSname());
}
} @After
public void destory(){
transaction.commit();
//关闭开启的资源
if(session!=null){
session.close();
}
if(sessionFactory!=null){
sessionFactory.close();
}
}
}

运行结果:

*************带有select子句的查询*********************
Hibernate:
select
students2x0_.SID as col_0_0_,
students2x0_.SNAME as col_1_0_,
students2x0_.SGENDER as col_2_0_
from
STUDENTS2 students2x0_
学号:1 姓名:小美 性别:女
学号:2 姓名:小泽 性别:男
学号:3 姓名:小敏 性别:女
同一个session并且同一个query对象下查询相同对象:
Hibernate:
select
students2x0_.SID as col_0_0_,
students2x0_.SNAME as col_1_0_,
students2x0_.SGENDER as col_2_0_
from
STUDENTS2 students2x0_
学号:1 姓名:小美 性别:女
学号:2 姓名:小泽 性别:男
学号:3 姓名:小敏 性别:女
**************不带select子句的查询**********************
Hibernate:
select
students2x0_.SID as col_0_0_
from
STUDENTS2 students2x0_
Hibernate:
select
students2x0_.SID as SID1_1_0_,
students2x0_.SNAME as SNAME2_1_0_,
students2x0_.SGENDER as SGENDER3_1_0_
from
STUDENTS2 students2x0_
where
students2x0_.SID=?
学号:1 姓别:女 姓名:小美
Hibernate:
select
students2x0_.SID as SID1_1_0_,
students2x0_.SNAME as SNAME2_1_0_,
students2x0_.SGENDER as SGENDER3_1_0_
from
STUDENTS2 students2x0_
where
students2x0_.SID=?
学号:2 姓别:男 姓名:小泽
Hibernate:
select
students2x0_.SID as SID1_1_0_,
students2x0_.SNAME as SNAME2_1_0_,
students2x0_.SGENDER as SGENDER3_1_0_
from
STUDENTS2 students2x0_
where
students2x0_.SID=?
学号:3 姓别:女 姓名:小敏
在同一session同一query1对象下查询相同的对象:
Hibernate:
select
students2x0_.SID as col_0_0_
from
STUDENTS2 students2x0_
学号:1 姓别:女 姓名:小美
学号:2 姓别:男 姓名:小泽
学号:3 姓别:女 姓名:小敏
在同一个session但是不是一个query对象下查询相同对象:
Hibernate:
select
students2x0_.SID as col_0_0_
from
STUDENTS2 students2x0_
学号:1 姓别:女 姓名:小美
学号:2 姓别:男 姓名:小泽
学号:3 姓别:女 姓名:小敏
在不同的session中,查询相同的对象:
Hibernate:
select
students2x0_.SID as col_0_0_
from
STUDENTS2 students2x0_
Hibernate:
select
students2x0_.SID as SID1_1_0_,
students2x0_.SNAME as SNAME2_1_0_,
students2x0_.SGENDER as SGENDER3_1_0_
from
STUDENTS2 students2x0_
where
students2x0_.SID=?
学号:1 姓别:女 姓名:小美
Hibernate:
select
students2x0_.SID as SID1_1_0_,
students2x0_.SNAME as SNAME2_1_0_,
students2x0_.SGENDER as SGENDER3_1_0_
from
STUDENTS2 students2x0_
where
students2x0_.SID=?
学号:2 姓别:男 姓名:小泽
Hibernate:
select
students2x0_.SID as SID1_1_0_,
students2x0_.SNAME as SNAME2_1_0_,
students2x0_.SGENDER as SGENDER3_1_0_
from
STUDENTS2 students2x0_
where
students2x0_.SID=?
学号:3 姓别:女 姓名:小敏

分析:以迭代器方式返回的查询,执行我们分成使用select子句和没有使用select子句的查询:

1)使用了select子句的查询,是不会使用缓存的

2)不使用select子句的查询,情况可以分为在同一个session下和不同的session下查询相同的对象。在同一个session下,第一次查询缓存中不存在的对象时,会先到数据库中查询要查对象的主键,然后依靠主键使用where子句限定主键,然后一一按照主键到数据库中执行SQL语句查询对象;再次查询相同对象时,会现在缓存中查询对象的编号,找到相同编号的返回,找不到的,再到数据库去按照编号查找。在不同session下,缓存一般不能使用。

Hibernate一级缓存(基于查询分析)

二、一级缓存相关介绍

1、hibernate一级缓存也称为“会话级缓存”、“session缓存”。

2、一级缓存的生命周期和session相同,session销毁,缓存也销毁。

3、一级缓存数据的使用范围,或者说是作用域为当前会话。

4、hibernate一级缓存的API

一级缓存无法取消,用两个方法管理。

evict():用于将某个对象从session中的一级缓存中清除。

clear():用于将一级缓存中的对象全部清除。

 package com.third; import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test; import com.third.Dao2.Students2; public class Test3 {
private static SessionFactory sessionFactory;
private static Session session;
private static Transaction transaction;
@Before
public void init(){
//先获取配置对象,匹配hibernate.cfg.xml文件
Configuration config=new Configuration().configure();
//获取注册服务对象(该对象中包含hibernate.cfg.xml中的<properties>和<maping>信息
ServiceRegistry serviceRegistry=new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry();
//获取sessionFactory对象,通过sessionFactory对象读取hibernate.cfg.xml文档信息,并通过<mapping>标签加载hbm.xml文件信息
sessionFactory=config.buildSessionFactory(serviceRegistry);
} @Test
public void test3(){
//通过sessionFactory对象获取session对象
session=sessionFactory.openSession();
//通过session对象开启事务,并且返回事务(transaction)对象
transaction=session.beginTransaction(); Students2 stu1=(Students2) session.get(Students2.class, 1);
Students2 stu2=(Students2) session.get(Students2.class, 2);
Students2 stu3=(Students2) session.get(Students2.class, 3); System.out.println("第一遍查询:");
System.out.println("学号:"+stu1.getSid()+" 姓名:"+stu1.getSname()+" 性别:"+stu1.getSgender());
System.out.println("学号:"+stu2.getSid()+" 姓名:"+stu2.getSname()+" 性别:"+stu2.getSgender());
System.out.println("学号:"+stu3.getSid()+" 姓名:"+stu3.getSname()+" 性别:"+stu3.getSgender()); //先使用evict()方法,然后在查询相同session下之前查过的对象
System.out.println("先使用evict()方法,然后在查询相同session下之前查过的对象:");
session.evict(stu1);
Students2 stu4=(Students2) session.get(Students2.class, 1);
System.out.println("学号:"+stu4.getSid()+" 姓名:"+stu4.getSname()+" 性别:"+stu4.getSgender()); //使用clear()方法,然后再查询相同session下之前查过的对象。
System.out.println("使用clear()方法,然后再查询相同session下之前查过的对象:");
session.clear();
Students2 stu5=(Students2) session.get(Students2.class, 1);
Students2 stu6=(Students2) session.get(Students2.class, 2);
Students2 stu7=(Students2) session.get(Students2.class, 3); System.out.println("学号:"+stu5.getSid()+" 姓名:"+stu5.getSname()+" 性别:"+stu5.getSgender());
System.out.println("学号:"+stu6.getSid()+" 姓名:"+stu6.getSname()+" 性别:"+stu6.getSgender());
System.out.println("学号:"+stu7.getSid()+" 姓名:"+stu7.getSname()+" 性别:"+stu7.getSgender());
} @After
public void destory(){
transaction.commit();
//关闭开启的资源
if(session!=null){
session.close();
}
if(sessionFactory!=null){
sessionFactory.close();
}
}
}

运行结果:

Hibernate:
select
students2x0_.SID as SID1_1_0_,
students2x0_.SNAME as SNAME2_1_0_,
students2x0_.SGENDER as SGENDER3_1_0_
from
STUDENTS2 students2x0_
where
students2x0_.SID=?
Hibernate:
select
students2x0_.SID as SID1_1_0_,
students2x0_.SNAME as SNAME2_1_0_,
students2x0_.SGENDER as SGENDER3_1_0_
from
STUDENTS2 students2x0_
where
students2x0_.SID=?
Hibernate:
select
students2x0_.SID as SID1_1_0_,
students2x0_.SNAME as SNAME2_1_0_,
students2x0_.SGENDER as SGENDER3_1_0_
from
STUDENTS2 students2x0_
where
students2x0_.SID=?
第一遍查询:
学号:1 姓名:小美 性别:女
学号:2 姓名:小泽 性别:男
学号:3 姓名:小敏 性别:女
先使用evict()方法,然后在查询相同session下之前查过的对象:
Hibernate:
select
students2x0_.SID as SID1_1_0_,
students2x0_.SNAME as SNAME2_1_0_,
students2x0_.SGENDER as SGENDER3_1_0_
from
STUDENTS2 students2x0_
where
students2x0_.SID=?
学号:1 姓名:小美 性别:女
使用clear()方法,然后再查询相同session下之前查过的对象:
Hibernate:
select
students2x0_.SID as SID1_1_0_,
students2x0_.SNAME as SNAME2_1_0_,
students2x0_.SGENDER as SGENDER3_1_0_
from
STUDENTS2 students2x0_
where
students2x0_.SID=?
Hibernate:
select
students2x0_.SID as SID1_1_0_,
students2x0_.SNAME as SNAME2_1_0_,
students2x0_.SGENDER as SGENDER3_1_0_
from
STUDENTS2 students2x0_
where
students2x0_.SID=?
Hibernate:
select
students2x0_.SID as SID1_1_0_,
students2x0_.SNAME as SNAME2_1_0_,
students2x0_.SGENDER as SGENDER3_1_0_
from
STUDENTS2 students2x0_
where
students2x0_.SID=?
学号:1 姓名:小美 性别:女
学号:2 姓名:小泽 性别:男
学号:3 姓名:小敏 性别:女

三、总结:

(1)一级缓存的数据的作用范围为一个session,缓存会随着session的销毁而销毁。

(2)其中通过get()、load()、和以Iterator(迭代器)方式返回无select子句查询都会使用到缓存,但是通过以list方式和Iterator(迭代器)方式返回的有select子句的查询不会使用缓存。

(3)其中以Iterator(迭代器)方式返回的hibernate查询都是先从数据库中查询对象的编号,然后到缓存中查找匹配的编号,找到了直接返回,找不到通过where子句限定以编号去数据库中查找,然后返回。

一级缓存查询的流程图:

Hibernate一级缓存(基于查询分析)

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,497
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,910
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,744
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,498
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,135
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,300