- 浏览: 140301 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
aa87963014:
很好,但是update/insert 是否加锁 。加锁对sel ...
数据库锁 -
RobustTm:
我的这种做法也可以添加A和B
但是换成更新就有问题
hibernate入门(十一):级联操作inversin属性 -
RobustTm:
这位仁兄可以提供一对多双向关联完整的代码不?
我碰到了问题,采 ...
hibernate入门(十一):级联操作inversin属性 -
cfeers:
markxing 写道谢谢分享。。。
不客气,呵呵。
struts2.0 struts.xml配置文件详解 -
markxing:
谢谢分享。。。
struts2.0 struts.xml配置文件详解
1.模拟缓存并简要说明缓存实现原理
在myhibernate项目下新建一个包com.asm.hibernate.test.cacheTest来说明与缓存有关的问题。首先看下面的一个模拟缓存程序,主要代码如下:
- package com.asm.hibernate.test.cacheTest;
- public class CacheSimulate {
- static Map cache = new HashMap();
- public static void main(String[] args) {
- addUser();
- //第一次查询,会去连接数据库查询
- User u1 = getUser(1);
- //第二次查询,直接从Map cache中取
- User u2 = getUser(1);
- //第三次查询,同样从cache中直接取
- User u3 = getUser(1);
- }
- static User getUser(int id) {
- String key = User.class.getName() + id;
- User user = (User) cache.get(key);
- if (user != null)
- return user;
- user = getUserFromDB(id);
- cache.put(key, user);
- return user;
- }
- static void addUser() {
- 省略代码,此方法的作用主要是向数据库添加一条记录,以方便查询操作
- }
- static User getUserFromDB(int id) {
- 省略代码,作用就是真正去查数据
- }
- }
package com.asm.hibernate.test.cacheTest; public class CacheSimulate { static Map cache = new HashMap(); public static void main(String[] args) { addUser(); //第一次查询,会去连接数据库查询 User u1 = getUser(1); //第二次查询,直接从Map cache中取 User u2 = getUser(1); //第三次查询,同样从cache中直接取 User u3 = getUser(1); } static User getUser(int id) { String key = User.class.getName() + id; User user = (User) cache.get(key); if (user != null) return user; user = getUserFromDB(id); cache.put(key, user); return user; } static void addUser() { 省略代码,此方法的作用主要是向数据库添加一条记录,以方便查询操作 } static User getUserFromDB(int id) { 省略代码,作用就是真正去查数据 } }
分析:重点来看getUser方法:当我们查询一个数据时,会首先在cache中查找,如果是第一次查询某数据,cache中没有存这个数据,会去查数据库。但是如果已经查过数据,便会在cache中查找到此数据,然后直接返回。可以从控制台中看到:hibernate只与数据库交互一次。
为什么要提出缓存的概念:在前面已经多次说过与数据库建立连接是非常耗资源,而且相当耗时。为了保证高效的查询性能,才提出了缓存的概念。缓存的原理:当第一次查询时会从数据库中查,当查出数据后会把数据保存在内存中,以后查询时直接从内存中查。当然,实际的缓存要远比此模拟程序复杂,但整个缓存机制是大同小异得,只是它要考虑到更多的细节。下面来谈谈缓存机制要解决的三个主要问题:
(1)向缓存中放数据:一般是发生在查询数据库时,因为每当我们不能从缓存中得到所需数据,便会去数据库中查找,查找完成后我们自然要把它更新到数据库中。
(2)从缓存中取数据:涉及到一个key的设置问题,比如我们在模拟程序中,key的取值来自“id + 类的类型信息”,这样就能保证key值的唯一性,因为如果仅以id作为key,那么其它的类会有相同的id时,在缓存中就不能区分。
(3)清掉缓存中失效的数据:当有其它的操作更新此数据时,原数据将不再正确,这时我们可以选择更新的方式来重新把新的数据更新到缓存中,也可以直接移除原数据,即调用 remove(key)。
2.Hibernate中的一级Session缓存:
- package com.asm.hibernate.test.cacheTest;
- public class HibernateCacheTest {
- public static void main(String[] args) {
- addUser();
- getUser(1);
- }
- static User getUser(int id) {
- Session s = null;
- User user = null;
- try {
- s = HibernateUtil.getSession();
- user = (User) s.get(User.class, id);
- System.out.println("userName:" + user.getName());
- // session缓存,当session未关闭时,再查询直接从缓存中获得数据。
- user = (User) s.get(User.class, id);
- System.out.println("userName:" + user.getName());
- // 如果我们清掉缓存,再查询时将会重新连库。
- s.evict(user);// 清掉指定的数据
- // s.clear();//清掉当前session缓存中的所有内容
- user = (User) s.get(User.class, id);
- System.out.println("userName:" + user.getName());
- } finally {
- if (s != null)
- s.close();
- }
- // 当上面的session关闭后,如果想再获取前面查询的数据,必须重新查库。
- try {
- s = HibernateUtil.getSession();
- user = (User) s.get(User.class, id);
- System.out.println("userName:" + user.getName());
- } finally {
- if (s != null)
- s.close();
- }
- return user;
- }
- static void addUser() {
- User user = new User();
- user.setName("genName");
- HibernateUtil.add(user);
- }
- }
package com.asm.hibernate.test.cacheTest; public class HibernateCacheTest { public static void main(String[] args) { addUser(); getUser(1); } static User getUser(int id) { Session s = null; User user = null; try { s = HibernateUtil.getSession(); user = (User) s.get(User.class, id); System.out.println("userName:" + user.getName()); // session缓存,当session未关闭时,再查询直接从缓存中获得数据。 user = (User) s.get(User.class, id); System.out.println("userName:" + user.getName()); // 如果我们清掉缓存,再查询时将会重新连库。 s.evict(user);// 清掉指定的数据 // s.clear();//清掉当前session缓存中的所有内容 user = (User) s.get(User.class, id); System.out.println("userName:" + user.getName()); } finally { if (s != null) s.close(); } // 当上面的session关闭后,如果想再获取前面查询的数据,必须重新查库。 try { s = HibernateUtil.getSession(); user = (User) s.get(User.class, id); System.out.println("userName:" + user.getName()); } finally { if (s != null) s.close(); } return user; } static void addUser() { User user = new User(); user.setName("genName"); HibernateUtil.add(user); } }
分析:经过上面的测试和相关说明我们可以得知如下结论:
(1)session的缓存只在session未关闭前有效,关闭后再查同的数据会重新连库
(2)我们可以手工清除session中的缓存:evict和clear
(3)如果我们清掉session中的缓存,或是第一次查询这个数据,都会引起连库
(4)save,update,savaOrUpdate,load,get,list,iterate,lock等方法都会将对象放在一级缓存中,具体可以在上例的基础上进行测试。
(5)session一级缓存不能控制缓存数量,所以在大批量操作数据时可能造成内存溢出,这时我们可以用evict,clear来清除缓存中的内容
(6)session在web开发应用中,一般只在一个用户请求时进行缓存,随后将会关闭,这个session的存活时间很短,所以它的作用不大,因此提出了二级缓存在概念。
3.二级缓存:
二级缓存通常是第三方来实现,而我们使用时只需要对它进行配置即可。下面演示使用二级缓存的具体步骤。
>>步骤一,在主配置文件中指明支持使用二级缓存:
<property name="hibernate.cache.use_second_level_cache">true</property>
我们也可以不配置此属性,因为默认就是打开二级缓存。
>>步骤二、配置第三方缓存机制:
<property name="hibernate.cache.provider_class">
org.hibernate.cache.OSCacheProvider
</property> 由于我们这里选择了OSCacheProvider(它貌似也是hibernate官方开发得缓存机制)来提供缓存,所以还需要把它的缓存配置文件放在src目录下以使配置能被读到,这里即是把hibernate解压下的etc目录中的oscache.properties文件复制到src目录下。
>>步骤三、两种方式指定要缓存的实体类,一种是在主配置文件中配置(注意class是完整的类名):<class-cache class="com.asm.hibernate.domain.User" usage="read-only"/>
另一种是在实体配置文件(映射文件)配置:比如在User.hbm.xml 的class元素下配置如下内容:<cache usage="read-only"/> 关于usage属性值的说明:
read-only:如果你的应用程序只需读取一个持久化类的实例,而无需对其修改,那么就可以对其进行只读
缓存。这是最简单,也是实用性最好的方法。
read-write: 如果应用程序需要更新数据,那么使用“读/写缓存”
比较合适。 如果应用程序要求“序列化事务”的隔离级别(serializable transaction isolation level),那么就决不能使用这种缓存策略。
nonstrict-read-write: 如果应用程序只偶尔需要更新数据(也就是说,两个事务同时更新同一记录的情况很不常见),也不需要十分严格的事务隔离,那么比较适合使用非严格读/写缓存
策略。
transactional: Hibernate的事务缓存策略提供了全事务的缓存支持,例如对JBoss TreeCache的支持。这样的缓存只能用于JTA环境中,你必须指定为其hibernate.transaction.manager_lookup_class属性。
发表评论
-
hibernate.cfg.xml文件详解(annotation 配置)
2010-08-26 15:57 1561一、 环境搭建和基本映 ... -
hibernate.cfg.xml文件详解
2010-08-26 15:56 742<?xml version='1.0' encoding ... -
hiberante入门(十七):简要总结及源码文档
2010-08-26 11:28 693十三、总结: 1.主配置与实体(映射)配置: 关于这些配置 ... -
hiberante入门(十六):一些细节理论
2010-08-26 11:26 746十二、一些细节问题分 ... -
hiberante入门(十五):事务相关-悲观乐观锁
2010-08-26 11:25 11641.事务引发的三层架构MV ... -
hiberante入门(十四):缓存2
2010-08-26 11:24 426>>步骤四、测试二 ... -
hiberante入门(十三):懒加载
2010-08-26 11:07 9274.懒加载: 在前面我们已经对懒加载有所提及,现在再借助一个 ... -
hiberante入门(十二):继承关系2
2010-08-26 11:03 963上接hiberante入门(十二 ... -
hiberante入门(十二):继承关系1
2010-08-26 11:01 8253.继承关系: 在前面的部门员工实例中,我们设定的员工只是普 ... -
hibernate入门(十一):级联操作inversin属性
2010-08-26 10:56 1501九、关联关系中的高级应用 1.级联操作: 在前面的一对多 ... -
hiberante入门(十):其它集合类型
2010-08-26 10:53 762八、其它集合类型 说明:在前面我们已经使用过set集合类型, ... -
hibernate入门(九):组件关系映射
2010-08-26 10:51 7735.组件关系映射: 典型实例:每个人有不同的名字,或者多个人 ... -
hibernate入门(八):多对多
2010-08-26 10:48 6444.多对多关系映射: 典型实例:一个学生可以有多个老师 ... -
hibernate入门(七):一对一
2010-08-26 10:42 7223.一对一关系映射: 典型的实例:一个人有一个身份证,而一个 ... -
hibernate入门(六):一对多
2010-08-26 10:36 6892.一对多关系映射: 上面提到的多个员工对应于一个部门,是多 ... -
hibernate入门(五):多对一
2010-08-26 10:32 6421.多对一关系映射: 一个部门有可以有多个员工,而一个员工只 ... -
hibernate入门(四):HQL QBC初步
2010-08-26 10:22 909四 完善工具类及HQL QBC ... -
hibernate入门(三):对象的三种状态
2010-08-26 10:20 687三 Session中的主要方法 ... -
hibernate入门(二):优化代码
2010-08-26 10:17 764二 优化代码 1.为会么要优化 在前面我们已经知道,获取S ... -
hibernate入门(一):第一个应用实例
2010-08-26 10:15 877一 第一个应用实例 1.搭建环境:新建一个名为Hiberna ...
相关推荐
Jupyter-Notebook
Jupyter-Notebook
高效甘特图模板下载-精心整理.zip
lstm Summary Framework: z = U>x, x u Uz Criteria for choosing U: • PCA: maximize projected variance • CCA: maximize projected correlation • FDA: maximize projected intraclass variance
OpenGL调试工具,适合图形开发者,包括视频开发,播放器开始以及游戏开发者。
全国行政区划shp最新图.zip
全国研究生招生与在校数据+国家线-最新.zip
Jupyter-Notebook
直播电商交流平台 SSM毕业设计 附带论文 启动教程:https://www.bilibili.com/video/BV1GK1iYyE2B
《林黛玉进贾府》课本剧剧本
2000-2020年沪深A股上市公司融资约束程度SA指数-最新数据发布.zip
PPT模版资料,PPT模版资料
CPA注会考试最新教材资料-最新发布.zip
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
内容概要:本文提供了一个完整的职工管理系统的C++源代码。通过面向对象的编程方法,实现了包括创建新职工、查询、增加、修改、删除、排序、统计以及存储和恢复职工数据在内的多个基本操作功能。该系统支持不同的用户角色(如管理员与老板),并通过菜单驱动方式让用户方便地进行相关操作。此外,还包括了错误检测机制,确保操作过程中的异常得到及时处理。 适合人群:有一定C++语言基础,特别是面向对象编程经验的程序员;企业管理人员和技术开发人员。 使用场景及目标:适用于中小型企业内部的人力资源管理部门或IT部门,用于维护员工基本信息数据库,提高工作效率。通过本项目的学习可以加深对链表、类和对象的理解。 阅读建议:建议先熟悉C++的基本语法和面向对象概念,再深入学习代码的具体实现细节。对于关键函数,比如exchange、creatilist等,应当重点关注并动手实践以加强理解。
Jupyter-Notebook
考研公共课历年真题集-最新发布.zip
Huawei-HKUST Joint Workshop on Theory for Future Wireless 15-16 September 2022 华为-香港科技大学未来无线理论联合研讨会 Speaker:Jingwen Tong
演出人员与观众疫情信息管理系统 SSM毕业设计 附带论文 启动教程:https://www.bilibili.com/video/BV1GK1iYyE2B
《林黛玉进贾府》课本剧剧本.pdf