首先我们应该弄清什么是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. HNU 13081 Even Up Solitaire解题报告

    题目大意:给定一个数组,若相邻的两个数之和为偶数,则将此两个数移除,通过这种方法将满足条件得数移除后数组还剩多少个数. 此题太水,不做解释.直接代码之: #include <stdio.h> ...

  2. PHP导出MYSQL数据库并压缩

    PHP可以一键导出MYSQL备份文件,并压缩存放,尽管phpMyAdmin有这功能,不过若你自己开发网站或者是为别人写CMS,你不应该要求别人用你程序的时候再去另外用phpMyAdmin备份MYSQL ...

  3. jquery proxy

    slice = Array.prototype.slice,// Bind a function to a context, optionally partially applying any // ...

  4. Spring AOP代理时 ClassCastException: $Proxy0 cannot be cast to (类型转换错误)

    Spring AOP代理时 ClassCastException: $Proxy0 cannot be cast to (类型转换错误) 问题: 今天在用AfterReturningAdvice时,a ...

  5. c#使用DotNetZip封装类操作zip文件(创建/读取/更新)实例

    DotnetZip是一个开源类库,支持.NET的任何语言,可很方便的创建,读取,和更新zip文件.而且还可以使用在.NETCompact Framework中.  下载地址在这里:http://dot ...

  6. FMS用AS来实现拉流

    application.onAppStart=function (){ this.myNC=new NetConnection(); this.myNC.onStatus=NC_onStatus; t ...

  7. HTML5 & CSS3初学者指南(3) – HTML5新特性

    介绍 本文介绍了 HTML5 的一些新特性.主要包含以下几个方面: Web 存储 地理位置 拖放 服务器发送事件 Web存储 HTML5 Web 存储的设计与构想是一个更好的机制来存储客户端的网络数据 ...

  8. Qt Quick编程(1)——QML的核心部分ECMAScript

    说道QML,不得不先说一下ECMAScript: ECMAScript语言的标准是由Netscape.Sun.微软.Borland等公司基于JavaScript和JScript锤炼.定义出来的. EC ...

  9. MyEclipse+Tomcat开发Web项目时修改内容不能及时显示问题解决方法

    问题描述:MyEclipse+Tomcat开发Web项目时,修改的内容不能从浏览器即时显示 原因:缓存问题 解决方法:开启Tomcat的Debug模式 点击如下图红色标记中的图标(Restart th ...

  10. Android 友盟分享详细集成过程及所遇问题解决

    最近项目需要针对微信.朋友圈.QQ.QQ空间集成友盟分享的功能,说实话,我也是第一次做,期间碰到过很多问题,这篇随笔就来写一下我是怎么集成友盟分享的,还有碰到哪些问题,都是怎样解决的! 其实集成友盟并 ...