一 Hibernate缓存

缓存是介于应用程序和数据库之间,对数据库中的数据复制一份到缓存中,其作用就是为了减少应用程序对数据库的访问,访问数据库时先从缓存中取,提高了程序的性能。Hibernate缓存分为一级缓存和二级缓存:

一级缓存:缓存范围是Session中共享,缓存的生命周期依赖于Session的生命周期,Session关闭后,缓存也关闭了,一级缓存是Hibernate内置的,不能卸除。

二级缓存:缓存范围是SessionFactory中共享,使用的是第三方插件,可插拨,缓存的生命周期依赖于应用的生命周期,应用结束时,缓存也就结束了生命周期。

二 一级缓存

当发生下面操作时,数据放入缓存:

1. save()

2. get()和load()

3. 使用HQL和QBC从数据库查询数据

package com;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.AnnotationConfiguration; public class Test { public static void main(String[] args) { SessionFactory factory = new AnnotationConfiguration().configure().buildSessionFactory();
Session session = factory.openSession();
Transaction t = session.beginTransaction(); t.begin();
User user1 = (User) session.get(User.class,1);
t.commit(); t.begin();
User user2 = (User) session.get(User.class,1);
t.commit(); System.out.println("user1==user2:"+(user1==user2)); session.close(); } }

 

结果显示,两个对象是同一个对象。

数据从缓存中清除:

1. evit()将指定的持久化对象从缓存中清除,释放对象所占用的内存资源,指定对象从持久化状态变为脱管状态,从而成为游离对象。 
2. clear()将缓存中的所有持久化对象清除,释放其占用的内存资源。

其他缓存操作:

1. contains()判断指定的对象是否存在于缓存中。
2. flush()刷新缓存区的内容,使之与数据库数据保持同步。

三 二级缓存

1.什么是二级缓存?

SessionFactory级别的缓存,可以跨越Session存在,可以被多个Session所共享。

2.适合放到二级缓存中:

(1)经常被访问

(2)改动不大

(3)数量有限

(4)不是很重要的数据,允许出现偶尔并发的数据。

这样的数据非常适合放到二级缓存中的。

用户的权限:用户的数量不大,权限不多,不会经常被改动,经常被访问。

例如组织机构。

思考:什么样的类,里面的对象才适合放到二级缓存中?

改动频繁,类里面对象特别多,BBS好多帖子,这些帖子20000多条,哪些放到缓存中,不能确定。除非你确定有一些经常被访问的,数据量并不大,改动非常少,这样的数据非常适合放到二级缓存中的。

3.二级缓存实现原理:

 Hibernate如何将数据库中的数据放入到二级缓存中?注意,你可以把缓存看做是一个Map对象,它的Key用于存储对象OID,Value用于存储POJO。首先,当我们使用Hibernate从数据库中查询出数据,获取检索的数据后,Hibernate将检索出来的对象的OID放入缓存中key 中,然后将具体的POJO放入value中,等待下一次再次向数据查询数据时,Hibernate根据你提供的OID先检索一级缓存,若有且配置了二级缓存,则检索二级缓存,如果还没有则才向数据库发送SQL语句,然后将查询出来的对象放入缓存中。

不同厂商提供了二级缓存的实现,如EH、OS、Swarm、JBoss等。

四 EH缓存实例

1.准备jar包

2.配置hibernate.cfg.xml

<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<property name="hibernate.cache.use_second_level_cache">true</property>

3.创建ehcache.xml文件

<?xml version="1.0" encoding="UTF-8"?>

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:noNamespaceSchemaLocation="ehcache.xsd">

<diskStore path="java.io.tmpdir" />

<defaultCache

maxElementsInMemory="10000"

eternal="false"

timeToIdleSeconds="120"

timeToLiveSeconds="120"

overflowToDisk="true"

diskPersistent="false"

diskExpiryThreadIntervalSeconds="120"

memoryStoreEvictionPolicy="LRU" />

</ehcache>

  

4.在需要被缓存的对象的配置文件class标签下添加cache子标签

 <cache usage="read-only"/>

5.测试

package com;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration; public class Test { public static void main(String[] args) { Configuration cfg = new Configuration();
cfg.configure("hibernate.cfg.xml");
SessionFactory factory = cfg.buildSessionFactory();
Session session = factory.openSession();
session.beginTransaction();
User user1 = (User) session.load(User.class,1);
session.getTransaction().commit();
session.close(); Session session1 = factory.openSession();
session1.beginTransaction();
User user2 = (User) session1.load(User.class,1);
session1.getTransaction().commit();
System.out.println("user1==user2:"+(user1==user2)); session1.close(); //factory.close(); } }

结果:

不是同一个对象,这个和一级缓存有区别。

其实二级缓存在存储数据的时候,做了一些特殊的处理,当数据从数据库加载到内存的时候,放入一级缓存(之前一级缓存的原理就不细说了),之后数据放入二级缓存了,但是放入二级缓存的数据却不是对象,这一点和一级缓存有区别,一级缓存放入的是一个具体的对象,对象的属性是有值的,所以可以直接获取(并且是同一个对象),当数据放入二级缓存的时候,hibernate内部把该对象装箱了(把具体对象转化成了object对象),但该object对象依然具有和和原始对象一样的属性只不过类型却是object类型(也称散装数据),装箱的同时也把该对象的类型字符串(包名加类型)也保存了一份,具体结构是,把该对象和该对象的类型字符串通过键值对保存了二级缓存(本质是一个map集合所以可以通过键值对保存),但键却很特殊的字符串,键是该类型字符串和该对象的oid(数据主键)的拼接,通过”#”分割,具体是类字符串#oid,对应该对象(object)。当从二级缓存中获取该数据(不能说是对象)的时候,会根据id和类字符去匹配二级缓存的所有key,如果能找到,则通过反射生产一个对象,并返回给用户(程序),这就很合理的解释了为什么不是同一个对象,因为是反射生产的,和很好的解释了为什么要保存该对象的类字符串,那么为什么要反射,而不直接吧该对象拆箱呢?,个人认为:如果拆箱(吧object转化为具体的po对象)就是一个对象,二级缓存是多个线程共享,如果多个用户同时公用同一个对象(内存地址的指向相同),会引发安全问题(反正这样不好)(摘自论坛回答)

参考:http://www.cnblogs.com/200911/archive/2012/10/09/2716873.html

 

Hibernate入门(四)的更多相关文章

  1. Hibernate入门(四)---------一级缓存

    Hibernate一级缓存 Hibernate的一级缓存就是指Session缓存,Session缓存是一块内存空间,用来存放相互管理的java对象,在使用Hibernate查询对象的时候,首先会使用对 ...

  2. SSH框架之hibernate《四》

    hibernate第四天     一.JPA相关概念         1.1JPA概述             全称是:Java Persistence API.是sun公司推出的一套基于ORM的规范 ...

  3. Hibernate第四天——查询方式

    Hibernate入门最后一天第四天,我们进行查询方式的更进一步的细化: 先看一下大致的Hibernate的提供的查询的方式: 1.对象导航查询 2.OID查询 3.HQL查询 4.QBC查询 5.本 ...

  4. 三大框架之hibernate入门

    hibernate入门   1.orm      hibernate是一个经典的开源的orm[数据访问中间件]框架           ORM( Object Relation Mapping)对象关 ...

  5. Hibernate入门详解

    学习Hibernate ,我们首先要知道为什么要学习它?它有什么好处?也就是我们为什么要学习框架技术? 还要知道    什么是Hibernate?    为什么要使用Hibernate?    Hib ...

  6. >hibernate的四种状态

    hibernate的四种状态 1.临时状态 与数据库中没有相对应的数据,也不在session的管理之中,一般是新new出来的对象 2.持久化状态 对象在session的管理中,最后会在事务提交后,在数 ...

  7. Hibernate入门案例及增删改查

    一.Hibernate入门案例剖析: ①创建实体类Student 并重写toString方法 public class Student { private Integer sid; private I ...

  8. 【原创】NIO框架入门(四):Android与MINA2、Netty4的跨平台UDP双向通信实战

    概述 本文演示的是一个Android客户端程序,通过UDP协议与两个典型的NIO框架服务端,实现跨平台双向通信的完整Demo. 当前由于NIO框架的流行,使得开发大并发.高性能的互联网服务端成为可能. ...

  9. Hibernate入门案例 增删改

    一.Hibernate入门案例剖析: ①创建实体类Student 并重写toString方法 public class Student { private Integer sid; private I ...

  10. Hibernate入门6.Hibernate检索方式

    Hibernate入门6.Hibernate检索方式 20131128 代码下载 链接: http://pan.baidu.com/s/1Ccuup 密码: vqlv Hibernate的整体框架已经 ...

随机推荐

  1. 为linux系统实现回收站

    在linux系统中,经常采用"rm *"或"rm -r *"操作删除一下文件,但是有时某些文件并不是我们想要删除的,但是已经被删除.很多时候都是悲剧的,数据是难 ...

  2. PPT要你好看---读书笔记

    PPT要你好看.主要是设计的思维. 下图,对于现阶段的我来说,收获最大的是毕业答辩PPT的制作. 以及整体的PPT制作思路.

  3. H5前端框架推荐合集

    Ionic ionic 吧开发流程都帮你做好了,已经不再是单纯的UI框架,而是开发框架了,非常适合快速开发.基于angular2,丰富的UI组件,大大改进的编程模型, Semantic UI 中文官网 ...

  4. SQL SERVER 的前世今生--各版本功能对比

    背景 今天举办的 Data Amp 大会上,微软向开发者们强调了 数据如何影响他们的应用和服务 ,顺道还宣布了几个小新闻.这个免费的线上研讨会不仅展示了未来的机器学习远景,还发布了 SQL Serve ...

  5. String,StringBuilder,StringBuffer的对比测试

    public class TestString { private static final int COUNT = 10000000; public static void main(String ...

  6. OC中自定义构造方法

    格式 -(instancetype)init(){ self=[super init] if(self){ } return self; } 自定义构造方法规范 1)一定是对象方法,以减号开头 2)返 ...

  7. NancyFx 2.0的开源框架的使用-Authentication

    新建一个空的项目 新建好了空的项目以后,接着通过NuGet安装一下三个包 Nancy Nancy.Hosting.Aspnet Nancy.ViewEnglines.Razor 然后在项目中添加Mod ...

  8. redis单机主从搭建

    tar zxvf redis-2.8.13.tar.gz cd redis-2.8.13 make 1.安装主库 mkdir /opt/redis/sbin -p mkdir    /opt/redi ...

  9. [刷题]算法竞赛入门经典(第2版) 4-2/UVa201 - Squares

    书上具体所有题目:http://pan.baidu.com/s/1hssH0KO 代码:(Accepted,20 ms) #include<iostream> #include<cs ...

  10. jquery之效果操作

    jQuery操作之效果 效果一共分五大类 一.基本 二.滑动 三.淡入淡出 四.自定义 五.设置 咱们先来看一下基本类 一.基本又分为 show() hide() toggle() html代码 &l ...