一 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. webapp万能选择器:iosselect

    iosselect是个什么东西? 移动端浏览器对于select的展示样式是不一致的,ios下是类似原生的picker,安卓下各浏览器展示各异,我们需要一个选择器组件来统一各端下各种浏览器的展示.下面是 ...

  2. mysql的一些使用操作

    1:如果空闲时间很长导致mysql报错: Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last pa ...

  3. C# Redis学习系列三:Redis配置主从

    Redis配置主从 主IP :端口      192.168.0.103 6666 从IP:端口       192.168.0.108 3333 配置从库 (1)安装服务: redis-server ...

  4. poj1125 Stockbroker Grapevine Floyd

    题目链接:http://poj.org/problem?id=1125 主要是读懂题意 然后就很简单了 floyd算法的应用 代码: #include<iostream> #include ...

  5. 使用MyEclipse生成实体类和Hibernate映射文件

    1.打开MyEclipse DataBase Explorer. 如上图,点击图中2便可切换到MyEclipse DataBase Explorer,若没有该图标,则点击图中1,便可选择MyEclip ...

  6. 我对RPC的理解

    1.简介 这篇文章将会用最直白的方式介绍RPC,以及实现RPC客户端的Ajax跨域调用的例子. RPC(Remote Procedure Call Protocol)--远程过程调用协议,它是一种通过 ...

  7. 学习笔记TF012:卷积网络简述

    ImageNet http://www.image-net.org ,图像标注信息数据库.每年举办大规模视觉识别挑战赛(ILSVRC).基于ImageNet数据库构建完成目标自动检测分类任务系统.20 ...

  8. 【图解HTTP】笔记摘要

    第1章 了解Web及网络基础 根据Web浏览器(Web客户端)地址栏中指定的URL,Web浏览器从Web服务器端获取文件资源(resource)等信息,从而显示出Web页面. CERN(欧洲核子研究组 ...

  9. UITextView 实现链接点击事件

    UILabel通过富文本可以实现图文混排,但是想要实现文字的点击效果好像不容易实现,这里有2种方法可以达到效果 YYLabel -->YYText框架 参考我之前的博客:http://www.c ...

  10. java 学习笔记1 java语言概述及开发环境

    高级语言运行机制 高级语言按程序的执行方式分为编译型和解释型两种. java语言比较特殊,Java程序的执行必须经过先编译后解释的步骤. 1 编译生成字节码,只面向JVM(.class) 2Jvm执行 ...