Hibernate框架——缓存(1)

来源:互联网 发布:centos如何安装git 编辑:程序博客网 时间:2024/06/06 19:16

一、缓存类型

1.1缓存分为三种:

1) 一级缓存(session级别缓存、事务级别缓存)  —— The First Level Cache

2) 二级缓存(sessionFactory级别缓存、进程或集群范围缓存)—— The Second Level Cache

3) 查询缓存


注意:

 一级缓存不能跨session存在,即每个session的缓存是相互间独立的,彼此不能共享数据。但是在多线程的情况下,可能会出现多个session需要共享同一份数据,为了避免频繁访问数据库,所以需要将数据存到缓存空间,供多个session对象使用,这种情况就需要用到二级缓存。

 

1.2 Hibernate文档中关于缓存的说明:

Hibernate 的 Session 在事务级别进行持久化数据的缓存操作。当然,也有可能分别为每个类(或集合),配置集群、或 JVM 级别(SessionFactory 级别)的缓存。你甚至可以为之插入一个集群的缓存。注意,缓存永远不知道其他应用程序对持久化仓库(数据库)可能进行的修改 (即使可以将缓存数据设定为定期失效)。


二、一级缓存

Hibernate的一级缓存也就是session级别的缓存是默认使用的,无需其他额外操作。只要使用了Session就会使用到以及缓存。

1、一级缓存示例:

1)建立一个实体类,使用注解生成一张表

<span style="font-size:18px;">/** * @Author: zsh * @Title: Users.java * @Description:用户实体类 * @Date:2016年9月3日 下午4:23:21 */@Entity@Table(name="cache_person")public class Person implements Serializable {private static final long serialVersionUID = 1L;private int id;// 用户IDprivate String name;// 用户姓名private String sex;// 用户性别public Person() {}/** * 带参构造器 * @param id * @param name * @param sex */public Person(int id, String name, String sex) {super();this.id = id;this.name = name;this.sex = sex;}@Overridepublic String toString() {return getClass().getName() + "@" + Integer.toHexString(hashCode()) + "\nUsers [id=" + id + ", name=" + name + ", sex=" + sex + "]";}@Id@SequenceGenerator(initialValue=1,allocationSize=1, name = "test_person")public int getId() {return id;}public String getName() {return name;}public String getSex() {return sex;}public void setId(int id) {this.id = id;}public void setName(String name) {this.name = name;}public void setSex(String sex) {this.sex = sex;}}</span>


(2)编写Hibernate配置文件

<span style="font-size:18px;"><!DOCTYPE hibernate-configuration PUBLIC"-//Hibernate/Hibernate Configuration DTD 3.0//EN""http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"><hibernate-configuration><!-- session工厂,负责管理session --><session-factory name="foo"><!-- 配置Oracle属性文件 --><!-- Hibernate方言 --><property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property><!-- 配置驱动 --><property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property><!-- 配置URL --><property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property><!-- 配置用户名 --><property name="hibernate.connection.username">scott</property><!-- 配置密码 --><property name="hibernate.connection.password">root</property><!-- 是否显示SQL语句 --><property name="show_sql">true</property><!-- 设置是否产生关系表 --><property name="hibernate.hbm2ddl.auto">update</property><!-- 格式化SQL语句 --><property name="hibernate.format_sql">true</property><!-- 配置映射文件 --><!-- Users表的映射,注意,这里映射的是类  --><mapping class="com.entity.Person"/></session-factory></hibernate-configuration></span>

(3)测试类

测试方法:通过查看是否向数据库发送sql语句判断是否使用了缓存,如果使用了缓存内的数据,就不会向数据库发送sql语句。

测试1.

<span style="font-size:18px;">/* * 测试一个session情况下 * 通过控制台查看程序会向数据库发送几次查询语句 */@Testpublic void queryUsersDemo1(){Session session = sf.openSession();//创建一个sessionPerson p= (Person )session.load(Person.class, 22);//第一次查询System.out.println(p);//使用查询结果Person p2  = (Users) session.load(Person.class, 22);//第二次查询System.out.println(p2);// 使用查询结果session.close();}</span>

测试1结果:

<span style="font-size:18px;">Hibernate:     select        person0_.id as id0_0_,        person0_.name as name0_0_,        person0_.sex as sex0_0_     from        person person0_     where        person0_.id=?com.entity.Person@37a1d638Person [id=22, name=周怡, sex=女]com.entity.Person@37a1d638Person [id=22, name=周怡, sex=女]</span>

第二次查询的时候,并没有向数据库发送sql语句,说明第二次查询使用的是session级别缓存内的数据。


测试2.

<span style="font-size:18px;">/* * 测试2个session情况下, * 通过控制台查看程序会向数据库发送几次查询语句 */@Testpublic void queryUsersDemo2(){Session session1 = sf.openSession();//创建一个sessionPerson p1  = (Person)session1.load(Person.class, 22);//第一次查询System.out.println(p1);//使用查询结果Session session2 = sf.openSession();//创建二个sessionPerson p2  = (Person) session2.load(Person.class, 22);//第二次查询System.out.println(p2);//使用查询结果session1.close();session2.close();}</span>

测试2.结果:

<span style="font-size:18px;">Hibernate:     select        person0_.id as id1_0_,        person0_.name as name1_0_,        person0_.sex as sex1_0_     from        cache_person person0_     where        person0_.id=?com.entity.Person@33858e1Person[id=0, name=张三, sex=男]Hibernate:     select        person0_.id as id1_0_,        person0_.name as name1_0_,        person0_.sex as sex1_0_     from        cache_person person0_     where        person0_.id=?com.entity.Person@1555984dPerson[id=0, name=张三, sex=男]</span>


用第二个session查询的时候,有向数据库发送sql语句,说明第二次查询没有使用缓存内的数据,和示例1进行比较,说明session级别的缓存只在一个session内有效。


2、一级缓存测试结果:

1) 一级缓存(session级别缓存)只在一个session中有效,不能跨session存在。

2) 当使用同一个session查询数据时,该数据会自动被保存到session缓存中,当下一次再访问该数据时,hibernate会自动从该session缓存中取出该数据。

3) 一级缓存(session级别缓存)的生命周期和session一致,session关闭后,该session对应的一级缓存也会关闭。





0 0
原创粉丝点击