



下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、Chapter6一级缓存与事务*课程回顾*1. 一对一关系2. 多对多关系*教学导航*1. Hibernate 一级缓存2. 对象基本查询方法3. Hibernate 事务一、Hibernate 一级缓存# 概念及介绍 #1.缓存?其实就是一块内存空间,将数据源(数据库或者文件)中的数据存放到缓存中.再次获取的时候 ,直接从缓存中获取.可以2. Hibernate 框架提供了两种缓存程序的性能!一级缓存 - 自带的不可卸载的.一级缓存的生命周期与 ses一致.一级缓存称为 ses级别的缓存.二级缓存 - 默认没有开启,需要手动配置才可以使用的.二级缓存可以在多个 ses3. SesSes享数据
2、,二级缓存称为是 ses对象的缓存概述Factory 级别的缓存(后续详解)接口中,有一系列的 java 的集合,这些 java 集合了 Ses级别的缓存(一级缓存).将对象存入到一级缓存中,ses没有结束生命周期,那么对象在 ses中存放着内存中包含 Ses含的是缓存对象!实例 - Ses的缓存(一些集合) - 集合中包4. 证明一级缓存的存在,编写查询的代码即可证明在同一个 Ses对象中两次查询,可以证明使用了缓存(参见示例 run1)5. Hibernate 框架是如何做到数据发生变化时进行同步操作的呢?使用 get 方法查询 User 对象然后设置 User 对象的一个属性,注意:没有
3、做 update 操作。发现,数据库也改变了。利用快照机制来完成的(SnapShot)快照就是当前一级缓存里面对象的散装中的数据(对象的属性,如 name、id)(参见示例 run3)# 一级缓存常用 API #一级缓存特点:当通过 ses的 save、update、saveOrUpdate 方法进行操作时,如果一级缓存中没有对象,那么会从数据库中查询到这些对象,并到一级缓存中。当通过 ses的 load、get、Query 的 list 等方法进行操作时,会先判断一级缓存中是否存在数据,如果没有才会从数据库获取,并且将查询的数据缓存中。到一级当调用 ses的 close 方法时,ses缓存将
4、清空。一级缓存常用的 API:clear():清空一级缓存。(参见示例 run4)evict(Object entity):清空一级缓存中指定的某个对象。(参见示例 run5) refresh():重新查询数据库,用数据库中的信息来更新一级缓存与快照区。Ses.flush():刷出缓存现在我举例来演示一级缓存常用的 API。(参见示例 run6)# 操作及验证 demo6.java#/* 证明:一级缓存是存在的*/Testpublic void run1()/ 1.得到sesSesses= HibernateUtils.getSes();Tranion tr = ses.begranion()
5、;/ 创建对象SysUser user = new SysUser();user.setUser_name(哈哈);user.setUser_password(123456);/ 保存用户,user一级存入到ses的缓存中通过查询也是一样的Serializable id = ses.save(user);System.out.prln(id);/ 获取对象,不会看到SQL语句SysUser user2 = ses.get(SysUser.class,id);System.out.prln(user2.getUser_name();/ 2.事务提交,并关闭sesmit();ses.close()
6、;二、Hibernate 事务# 事务相关的概念#1.事务事务就是逻辑上的一组操作,组成事务的各个执行单元,操作要么全都成功,要么全都失败.转账的例子:2. 事务的四大特性给美美转钱,扣钱,加钱。两个操作组成了一个事情!原子性一致性性 持久性-事务不可分割.事务执行的前后数据的完整性保持一致.一个事务执行的过程中,不应该受到其他的事务的干扰.事务一旦提交,数据就保持到数据库中.3. 如果不考虑脏读不可重复读多次查询结果不一致.虚读多次查询结构不一致.性:一些读-一个事务读到了另一个事务未提交的数据.一个事务读到了另一个事务已经提交的 update 数据,导致-一个事务读到了另一个事务已经提交的
7、 insert 数据,导致4. 通过设置数据库的MITED级别来解决上述读未提交:它所有的问题MITTEDREPEATABLE_READ SERIALIZABLE读已提交:重复读:串行化:脏读,可能发生不可重复读与虚读.脏读,不可重复读:可能发生虚读解决所有问题 不允许两个事务,同时操作一个目标数据。(效率低下,但操作安全是最安全的)ORACLE默认的是事务默认的事务级别级别MITTEDREPEATABLE_READ5. 如果想在 Hibernate 的框架中来设置级别,需要在 hibernate.cfg.xml的配置文件中通过来配置通过:hibernate.connection.isolat
8、ion = 4 来配置取值1Readmitted isolation2Read committed isolation4Repeatable read isolation 8Serializable isolation在 hibernate.cfg.xml 文件中配置4*丢失更新*1. 如果不考虑性,也会产生写入数据,这一类叫丢失更新的问题。 2. 例如:两个事务同时对某一条做修改,就会丢失更新。* A 事务和 B 事务同时获取到一条数据,同时再做修改* 如果 A 事务修改完成后,提交了事务* B 事务修改完成后,不管是提交还是回滚,如果不做处理,都会对数据产生影响 3. 解决方案有两种* 悲
9、观锁* 采用的是数据库提供的一种锁机制,如果采用做了这种机制,在 SQL 语句的后面添加 for update 子句* 当 A 事务在操作该条时,会把该条锁起来,其他事务是不能操作这条的。* 只有当 A 事务提交后,锁了,其他事务才能操作该条* 乐观锁* 采用版本号的机制来解决的。会给表结构添加一个字段 ver=0,默认值是 0* 当 A 事务在操作完该条,提交事务时,会先检查版本号,如果发生版本号的值相同时,才可以提交事务。同时会更新版本号 ver=1.* 当 B 事务操作完该条时,提交事务时,会先检查版本号,如果发现版本不同时,程序会出现错误。4. 使用 Hibernate 框架解决丢失更
10、新* 悲观锁* 使用 ses.get(Customer.class, 1,LockMode.UPGRADE); 方法说到这里,就提到了 hibernate 的加锁模式:LockMode.NONE:无锁机制。LockMode.WRITE:Hibernate 在 Insert 和 Update的时候会自动获取。hibernate的,与数据库加锁无关。LockMode.UPGRADE:利用数据库的 for update 字句加锁。 这种模式需要区分前三种模式,该模式是与数据有关的(for update)* 乐观锁* 1.在对应的 JavaBean 中添加一个属性,名称可以是任意的。例如:privat
11、e eger ver; 提供 get 和 set 方法* 2.在的配置文件中,提供标签即可 *绑定本地的 Ses* 1. 之前在讲 JavaWEB 的事务的时候,需要在业务层使用 Connection 来开启事务,* 一种是通过参数的方式传递下去* 另一种是把 Connection 绑定到 ThreadLocal 对象中 2. 现在的 Hibernate 框架中,使用 ses 对象开启以需要来传递ses 对象,框架提供了 ThreadLocal 的方式* 需要在 hibernate.cfg.xml 的配置文件中提供配置* threadLockMode.READ:Hibernate 在的时候会自
12、动获取。 这三种加锁模式是供getCurrentSes()方法,获取当前的 Ses 对象。并且该 Ses 对象不用手动关闭,线程结束了,会自动关闭。public sic SesgetCurrentSes()return factory.getCurrentSes();* 注意:想使用 getCurrentSes()方法,必须要先配置才能使用。示例弄清三、Hibernate get 和 load 查询/* 演示基本对象的查询 */public class Demo /* get()方法: 查询一个对象*/Testpublicvoidtest1()Sesses= HibernateUtil.get
13、Ses();Tranion tx = ses.begranion();Customer cust = ses.get(Customer.class,1);Set orders = cust.getOrders();System.out.prln(cust.getName()+的订单:);for (Order order : orders) System.out.prln(order.getOrderno();* 重新 HibernateUtil 的工具类,使用 SesFactory 的mit();ses.close();/* load()方法: 查询一个对象*/Testpublicvoidte
14、st2()Sesses= HibernateUtil.getSes();Tranion tx = ses.begranion();Customer cust = ses.load(Customer.class,1);Set orders = cust.getOrders();System.out.prln(cust.getName()+的订单:);for (Order order : orders) System.out.prln(order.getOrderno();mit();ses.close();# get 和 load 的区别#要从数据库中得到一个对象,通常有两种方式,一种是通过 s
15、es.get()方法,另一种就是通过 ses.load()方法,然后其实这两种方法在获得一个实体对象时是有区别的,在查询性能上两者是不同的。1、load 加载方式当使用 load 方法来得到一个对象时,此时 hibernate 会使用延迟加载的机制来加载这个对象,即:当使用 ses.load()方 法来加载一个对象时,此时并不会发出 sql 语句,当前得到的这个对象其实是一个对象,这个对象只保存了实体对象的 id 值,只有当语句,从数据库中去查询要使用这个对 象,得到其它属性时,这个时候才会发出 sql的对象。ses= HibernateUtil.openSes();/* 通过load 的方式
16、加载对象时,会使用延迟加载机制,此时并不会发出 sql 语句,只有当要使用的时候才会从数据库中去查询需*/User user = (User)ses.load(User.class, 2);看到,如果仅仅是通过 load 来加载的 User 对象,此时从控制台我们会发现并不会从数据库中查询出该对象,即并不会发出 sql 语句,但如果用该对象时:要使ses= HibernateUtil.openSes();User user = (User)ses.load(User.class, 2);System.out.prln(user);此时看到控制台会发出了 sql 查询语句,会将该对象从数据库中查
17、询出来:2、get 加载方式相对于 load 的延迟加载方式,get 就直接的多,当使用 ses.get()方法来得到一个对象时,不管中查询出来:使不使用这个对象,此时都会发出 sql 语句去从数据库ses= HibernateUtil.openSes();/* 通过get 方法来加载对象时,不管使不使用该对象,都会发出sql 语句,从数据库中查询*/User user = (User)ses.get(User.class, 2);此时通过 get 方式来得到 user 对象,但是并没有使用它,但是发现控制台会输出 sql 的查询语句:因此可以看到,使用 load 的加载方式比 get 的加载
18、方式仅仅从性能方面来讲要好一些,因为 load 加载时,得到的只是一个再去从数据库中查询。对象,当真正需要使用这个对象时3、 存在当了解了 load 和 get 的加载机制以后,小问题:此时来看看这两种方式会出现的一些如果使用 get 方式来加载对象,当试图得到一个 id 不存在的对象时,此时会报 NullPoException 的异常ses= HibernateUtil.openSes();/* 当通过get 方式试图得到一个id 不存在的user 对象时,此时会报NullPoException 异常*/User user = (User)ses.get(User.class, 20);Sy
19、stem.out.prln(user.getUsername();此时看控制台的输出信息,会报空指针的异常这是因为通过 get 方式会去数据库中查询出该对象,但是这个 id 值不存在,所以此时 user 对象是 null,所以就会报 NullPoException 的异常了。如果使用 load 方式来加载对象,当报 ObjectNotFoundException 异常:试图得到一个 id 不存在的对象时,此时会ses= HibernateUtil.openSes();/* 当通过get 方式试图得到一个id 不存在的user 对象时,此时会报ObjectNotFoundException异常*
20、/User user = (User)ses.load(User.class, 20);System.out.prln(user.getId();ln(user.getUsername();System.out.pr.hibernaazyInitializationException 异常接下来再来看一个例子:public claserpublic UserloadUser(id)Sesses= null;Traniontx = null;Useruser =null;tryses= HibernateUtil.openSes();tx = ses.begranion();user = (User)ses.load(User.class,1);mit();catch (Exception e)e.prStackTrace();tx.rollback();finallyHibernateUtil.close(ses);return user;Testpublic void testLazy06()Useruser= new User();User user = user.loadUser(2);System.out.prln(user);模拟了一个 User这样的对象,然后在测试用例里面来通过 lo
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 善于归纳西方政治制度的明确性试题及答案
- 机电工程用户体验设计试题
- 软考网络工程师考试重点知识汇编试题及答案
- 数据传输中的延时分析试题及答案
- 新能源与环保:环保型电力生产与消费模式创新
- 2025年互联网金融平台用户信任维护与金融科技产品安全策略研究
- 如何更好地服务于公共政策的部门协作试题及答案
- 机电工程课程教学案例与试题及答案解读
- 安全对撞测试题及答案
- 安全大比武试题及答案
- KCA试题库完整版
- 2024年新版药品管理法培训
- DB51T 2845-2021 连续玄武岩纤维生产原料技术规范
- 2025届湖南省高考化学第一轮复习模拟选择题-化学与生活43道(附答案)
- 医院培训课件:《血液净化质量控制标准解读》
- GB/T 44908-2024风力发电场技改升级安全要求及评价方法
- 家具翻新合同模板
- 二次元行业的发展环境分析
- 工厂转让协议书的
- (建筑施工工艺标准)钢结构制作施工工艺标准
- 10SG614-2 砌体填充墙构造详图(二)(与主体结构柔性连接)
评论
0/150
提交评论