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

一、hibernate查询的几种方式

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

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

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

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

通过传入实体类名和该类对象的唯一标识符两个参数,返回一个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对象在查询相同对象正常情况下是不会使用缓存。

2、通过session的load()方法

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

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

通过传入实体类名和该类对象的唯一标识符两个参数,返回一个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接口,我们找到了两个方法,是将查询结果返回的。

以List的方式返回查询结果

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

(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()方法,不会使用缓存。

(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下,缓存一般不能使用。

二、一级缓存相关介绍

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一级缓存(基于查询分析)的更多相关文章

  1. Hibernate一级缓存测试分析

    Hibernate 一级缓存测试分析 Hibernate的一级缓存就是指Session缓存,此Session非http的session会话技术,可以理解为JDBC的Connection,连接会话,Se ...

  2. hibernate 一级缓存,二级缓存,查询缓存

    1.一级缓存是session级的缓存,session结束即事务提交,session关闭,缓存清除.效果不大 get方式:一个session内,第二次查询不连数据库.适用于一级缓存 load方式:懒加载 ...

  3. hibernate一级缓存,二级缓存和查询缓存

    一级缓存 (必然存在)  session里共享缓存,伴随session的生命周期存在和消亡:   1. load查询实体支持一级缓存 2. get查询实体对象也支持 3. save保存的实体对象会缓存 ...

  4. hibernate一级缓存

    理解 Hibernate 一级缓存 Hibernate 一级缓存默认是打开,不需要任何的配置.实际上,你无法强制禁止它的使用. 如果你理解了一级缓存实际上和会话是关联的,就很容易理解一级缓存.总所周知 ...

  5. hibernate一级缓存及对象的状态

    hibernate中实体类对象的状态 在hibernate中实体类对象有三种状态 (1)瞬时态(临时态) 瞬时态:即我们自己创建一个对象,还没有保存到数据库就叫临时态,其实也可以说是对像没有id值,跟 ...

  6. Hibernate一级缓存(补)

    ------------------siwuxie095                                 什么是缓存         缓存是介于应用程序和永久性数据存储源(如:硬盘上的 ...

  7. 转载 hibernate一级缓存和二级缓存的区别

    文章来源:http://blog.csdn.net/defonds/article/details/2308972     hibernate一级缓存和二级缓存的区别 缓存是介于应用程序和物理数据源之 ...

  8. Hibernate一级缓存和三种状态

    Hibernate一级缓存又称session缓存,生命周期很短,跟session生命周期相同. 三种状态:1.transient(瞬时态):刚new出来的对象,既不在数据库中,也不在session管理 ...

  9. Mybatis的缓存——一级缓存和源码分析

    目录 什么是缓存? 一级缓存 测试一. 测试二. 总结: 一级缓存源码分析: 1. 一级缓存到底是什么? 得出结论: 2. 一级缓存什么时候被创建? 3. 一级缓存的执行流程 结论: 一级缓存源码分析 ...

随机推荐

  1. Spark中的wordCount程序实现

    import org.apache.spark.SparkConf; import org.apache.spark.api.java.JavaPairRDD; import org.apache.s ...

  2. Newman的 power law 参数估计的程序matlab(转载)

    转自:http://blog.sciencenet.cn/blog-4716-46173.html 对于幂率分布的估计问题是个很复杂的问题(..., the empirical detection a ...

  3. Eclipse常见操作

    Eclipse打开Package Explorer Window > Show View > Other Java > Package Explorer 然后可以将其拖拽到Eclip ...

  4. Eclipse 打开文件所在文件夹

    右击文件 > Show In > System Explorer

  5. Linux文件权限与目录配置

    一.linux文件属性 用户组概念:假如主机有两个团体,第一个团体名为projecta,里面有class1,class2,class3:第二个团体名为projecb,里面有class4,class5, ...

  6. JSP中使用Taglib

    http://blog.163.com/jany_1016/blog/static/4604400620091112114127341/ http://blog.csdn.net/yuebinghao ...

  7. CCNA网络工程师学习进程(8)访问控制列表ACL

    前面几节我们介绍了路由器的路由配置,接下来几节我们将介绍路由器的高级配置应用,包括ACL.NAT.DHCP.PPP.VPN和远程连接等的配置.     (1)ACL概述:   ACL(Access C ...

  8. Recurrent Neural Network系列3--理解RNN的BPTT算法和梯度消失

    作者:zhbzz2007 出处:http://www.cnblogs.com/zhbzz2007 欢迎转载,也请保留这段声明.谢谢! 这是RNN教程的第三部分. 在前面的教程中,我们从头实现了一个循环 ...

  9. Spring AOP中的动态代理

    0  前言 1  动态代理 1.1 JDK动态代理 1.2 CGLIB动态代理 1.2.1 CGLIB的代理用法 1.2.2 CGLIB的过滤功能 2  Spring AOP中的动态代理机制 2.1  ...

  10. 开源半成品的Web版工作流模板设计器(基于AngularJS 2和Redux), 还在继续填坑中

    先上个图: 很多企业内部的应用都需要有个工作流平台(插件),无奈灵活方便好用且能够自行更改代码定制嵌入的实在不多,只好自己动手慢慢搞. https://github.com/shibamo/99-fl ...