持久化数据库第四天ppt课件

上传人:钟*** 文档编号:1542208 上传时间:2019-10-24 格式:PPT 页数:37 大小:2.19MB
返回 下载 相关 举报
持久化数据库第四天ppt课件_第1页
第1页 / 共37页
持久化数据库第四天ppt课件_第2页
第2页 / 共37页
持久化数据库第四天ppt课件_第3页
第3页 / 共37页
点击查看更多>>
资源描述
hibernate 第四天,1,知识点一、 hibernate 二级缓存,2,使用C3P0连接池,知识点1:配置c3p0连接池,* 在hibernate.cfg.xml文件中增加如下配置 org.hibernate.connection.C3P0ConnectionProvider 5 20 120 3000 true,* 引入c3p0-0.9.1.jar,3,多个事务并发运行时的并发问题,知识点2:概念,4,多个事务并发运行时的并发问题,知识点2:案例,5,多个事务并发运行时的并发问题,知识点2: 丢失更新,6,多个事务并发运行时的并发问题,知识点2:脏读,7,多个事务并发运行时的并发问题,知识点2: 虚读(幻读),8,多个事务并发运行时的并发问题,知识点2: 不可重复读,9,Hibernate数据库级别的并发,知识点3: ANSI 事务隔离级别 ANSI SQL 标准定义了隔离级别,但并不是SQL数据库独有.JTA也定义了同样的隔 离级别.级别越高,成本越高,10,Hibernate数据库级别的并发,设置隔离级别 每个数据库连接都有默认的隔离级别,通常是读已提交或可重复读.可以通 过数据库配置设置,也可在应用程序中设置.例如Hibernate: hibernate.connection.isolation = 4 1Read uncommitted isolation 2Read committed isolation 4Repeatable read isolation 8Serializable isolation 注意:* Hibernate不可能改变在受管环境下由应用服务器提供的数据库连接 的隔离级别,只能通过改变应用服务器配置的方式来改变. * 设置隔离级别是全局选项,会影响所有的连接和事务.有时需要为某个特定 事务指定更多的限制. * Hibernate依赖于乐观的并发控制,使用版本检查和悲观锁实现附加的锁支 持.,知识点3: ANSI 事务隔离级别,11,管理session,尽管让程序自主管理 Session 对象的生命周期也是可行的, 但是在实际 Java 应用中, 把管理 Session 对象的生命周期交给 Hibernate 管理, 可以简化 Java 应用程序代码和软件架构 Hibernate 3 自身提供了三种管理 Session 对象的方法 Session 对象的生命周期与本地线程绑定 Session 对象的生命周期与 JTA 事务绑定 Hibernate 委托程序管理 Session 对象的生命周期 在 Hibernate 的配置文件中, hibernate.current_session_context_class 属性用于指定 Session 管理方式, 可选值包括 thread: Session 对象的生命周期与本地线程绑定 jta*: Session 对象的生命周期与 JTA 事务绑定 managed: Hibernate 委托程序来管理 Session 对象的生命周期,知识点4:管理session,12,管理session,如果把 Hibernate 配置文件的 hibernate.current_session_context_class 属性值设为 thread, Hibernate 就会按照与本地线程绑定的方式来管理 Session Hibernate 按以下规则把 Session 与本地线程绑定 当一个线程(threadA)第一次调用 SessionFactory 对象的 getCurrentSession() 方法时, 该方法会创建一个新的 Session(sessionA) 对象, 把该对象与 threadA 绑定, 并将 sessionA 返回 当 threadA 再次调用 SessionFactory 对象的 getCurrentSession() 方法时, 该方法将返回 sessionA 对象 当 threadA 提交 sessionA 对象关联的事务时, Hibernate 会自动清理 sessionA 对象的缓存, 然后提交事务, 关闭 sessionA 对象. 当 threadA 撤销 sessionA 对象关联的事务时, 也会自动关闭 sessionA 对象 若 threadA 再次调用 SessionFactory 对象的 getCurrentSession() 方法时, 该方法会又创建一个新的 Session(sessionB) 对象, 把该对象与 threadA 绑定, 并将 sessionB 返回,知识点4: Session 对象的生命周期与本地线程绑定,13,管理session,* 在hibernate.cfg.xml文件中增加 thread * 不是调用sessionFactory.openSession().而是调用sessionFactory. getCurrentSession().获取session对象.从当前的线程提取session, * 当前线程如果存在session对象,取出直接使用 * 当前线程如果不存在session对象,获取一个新的session对象和当前的线程绑定,知识点4:在hibernate中如何配置,14,管理session 范例代码,15,二级缓存,缓存(Cache): 计算机领域非常通用的概念。它介于应用程序和永久性数据存储源(如硬盘上的文件或者数据库)之间,其作用是降低应用程序直接读写永久性数据存储源的频率,从而提高应用的运行性能。缓存中的数据是数据存储源中数据的拷贝。缓存的物理介质通常是内存,知识点5:理解缓存定义,16,二级缓存,Hibernate中提供了两个级别的缓存 第一级别的缓存是 Session 级别的缓存,它是属于事务范围的缓存。这一级别的缓存由 hibernate 管理的,一般情况下无需进行干预 第二级别的缓存是 SessionFactory 级别的缓存,它是属于进程范围的缓存 SessionFactory 的缓存可以分为两类: 内置缓存: Hibernate 自带的, 不可卸载. 通常在 Hibernate 的初始化阶段, Hibernate 会把映射元数据和预定义的 SQL 语句放到 SessionFactory 的缓存中, 映射元数据是映射文件中数据的复制, 而预定义 SQL 语句时 Hibernate 根据映射元数据推到出来的. 该内置缓存是只读的. 外置缓存(二级缓存): 一个可配置的缓存插件. 在默认情况下, SessionFactory 不会启用这个缓存插件. 外置缓存中的数据是数据库数据的复制, 外置缓存的物理介质可以是内存或硬盘,知识点6:理解二级缓存定义,17,二级缓存,知识点7:hibernate二级缓存的结构,18,二级缓存,两个并发的事务同时访问持久层的缓存的相同数据时, 也有可能出现各类并发问题. 二级缓存可以设定以下 4 种类型的并发访问策略, 每一种访问策略对应一种事务隔离级别 非严格读写(Nonstrict-read-write): 不保证缓存与数据库中数据的一致性. 提供 Read Uncommited 事务隔离级别, 对于极少被修改, 而且允许脏读的数据, 可以采用这种策略 读写型(Read-write): 提供 Read Commited 数据隔离级别.对于经常读但是很少被修改的数据, 可以采用这种隔离类型, 因为它可以防止脏读 事务型(Transactional): 仅在受管理环境下适用. 它提供了 Repeatable Read 事务隔离级别. 对于经常读但是很少被修改的数据, 可以采用这种隔离类型, 因为它可以防止脏读和不可重复读 只读型(Read-Only):提供 Serializable 数据隔离级别, 对于从来不会被修改的数据, 可以采用这种访问策略,知识点8:理解二级缓存的并发访问策略,19,二级缓存,适合放入二级缓存中的数据: 很少被修改 不是很重要的数据, 允许出现偶尔的并发问题 不适合放入二级缓存中的数据: 经常被修改 财务数据, 绝对不允许出现并发问题 与其他应用数据共享的数据,知识点9:缓存中存放的数据,20,二级缓存,Hibernate 的二级缓存是进程或集群范围内的缓存, 缓存中存放的是对象的散装数据 二级缓存是可配置的的插件, Hibernate 允许选用以下类型的缓存插件: EHCache: 可作为进程范围内的缓存, 存放数据的物理介质可以使内存或硬盘, 对 Hibernate 的查询缓存提供了支持 OpenSymphony OSCache:可作为进程范围内的缓存, 存放数据的物理介质可以使内存或硬盘, 提供了丰富的缓存数据过期策略, 对 Hibernate 的查询缓存提供了支持 SwarmCache: 可作为集群范围内的缓存, 但不支持 Hibernate 的查询缓存 JBossCache:可作为集群范围内的缓存, 支持 Hibernate 的查询缓存 4 种缓存插件支持的并发访问策略(x 代表支持, 空白代表不支持),知识点10:缓存提供的供应商,21,二级缓存,1 拷贝ehcache-1.5.0.jar到当前工程的lib目录下 2 开启二级缓存 true 3 要指定缓存的供应商 org.hibernate.cache.EhCacheProvider 4 指定使用二级缓存的类 * 方法一 在使用类的*.hbm.xml配置 选择需要使用二级缓存的持久化类, 设置它的二级缓存的并发访问策略, 元素的 cache 子元素表明 Hibernate 会缓存对象的简单属性, 但不会缓存集合属性, 若希望缓存集合属性中的元素, 必须在 元素中加入 子元素,知识点11_1:配置进程范围内的二级缓存(配置ehcache缓存),22,二级缓存,* 方法二 在hibernate.cfg.xml文件中配置(建议) 5 配置ehcache默认的配置文件ehcache.xml(名字固定)(放在类路径下),知识点11_2:配置进程范围内的二级缓存(配置ehcache缓存),23,二级缓存,ehcache.xml文件 ,知识点11:配置进程范围内的二级缓存(配置ehcache缓存),所有配置的二级缓存的默认使用的配置,24,二级缓存,:指定一个目录, 当 EHCache 把数据写到硬盘上时, 将把数据写到这个文件目录下. 默认是C:WINDOWSTemp : 设置缓存的默认数据过期策略 设定具体的命名缓存的数据过期策略 每个命名缓存代表一个缓存区域,每个缓存区域有各自的数据过期策略。命名缓存机制使得用户能够在每个类以及类的每个集合的粒度上设置数据过期策略。,知识点11:配置进程范围内的二级缓存(配置ehcache缓存),25,二级缓存,cache元素的属性 name:设置缓存的名字,它的取值为类的全限定名或类的集合的名字 maxElementsInMemory :设置基于内存的缓存中可存放的对象最大数目 eternal:设置对象是否为永久的,true表示永不过期,此时将忽略timeToIdleSeconds 和 timeToLiveSeconds属性; 默认值是false timeToIdleSeconds:设置对象空闲最长时间,以秒为单位, 超过这个时间,对象过期。当对象过期时,EHCache会把它从缓存中清除。如果此值为0,表示对象可以无限期地处于空闲状态。 timeToLiveSeconds:设置对象生存最长时间,超过这个时间,对象过期。 如果此值为0,表示对象可以无限期地存在于缓存中. 该属性值必须大于或等于 timeToIdleSeconds 属性值 overflowToDisk:设置基于内在的缓存中的对象数目达到上限后,是否把溢出的对象写到基于硬盘的缓存中 diskPersistent 当jvm结束时是否持久化对象 true false 默认是false diskExpiryThreadIntervalSeconds 指定专门用于清除过期对象的监听线程的轮询时间,知识点11:配置进程范围内的二级缓存(配置ehcache缓存),26,二级缓存,public void testCache() Session session=sf.openSession(); Transaction tx=session.beginTransaction(); Customer c=(Customer)session.load(Customer.class, 1); System.out.println(c.getName(); mit(); session.close(); session=sf.openSession(); tx=session.beginTransaction(); c=(Customer)session.load(Customer.class, 1); System.out.println(c.getName(); /cn.c3p0.Customer1225c6 System.out.println(c); mit(); session.close();,知识点12:测试二级缓存和散列数据,27,二级缓存,session=sf.openSession(); tx=session.beginTransaction(); c=(Customer)session.load(Customer.class, 1); System.out.println(c.getName(); /cn.c3p0.Customer1353550 System.out.println(c); /测试散列 是重组的对象 mit(); session.close(); ,知识点12:测试二级缓存和散列数据,需要引入两个jar包 在srping下能找到 libconcurrentbackport-util-concurrent.jar libcommons-logging.jar,28,二级缓存,public void testUpdate() Session session=sf.openSession(); Transaction tx=session.beginTransaction(); Customer c=(Customer)session.load(Customer.class, 1); System.out.println(c.getName(); c.setName(张三); mit(); session.close(); session=sf.openSession(); tx=session.beginTransaction(); c=(Customer)session.load(Customer.class, 1); System.out.println(customer.getName(); /张三 mit(); session.close(); ,知识点13:测试一级缓存更新数据会同步到二级缓存,29,二级缓存,知识点14:测试二级缓存的数据存放到临时目录,配置Order对象的缓存,查看临时目录,缓存中只能放10个对象,30,二级缓存,知识点14:测试二级缓存的数据存放到临时目录,/测试缓存溢出存放到临时目录 Test public void testowerFlow() Session session=sf.openSession(); Transaction tx=session.beginTransaction(); Query query=session.createQuery(“ from Order o“); /30个对象 query.list().size(); mit(); session.close(); ,31,二级缓存,Hibernate 提供了和查询相关的缓存区域: 时间戳缓存区域: org.hibernate.cahce.UpdateTimestampCache 时间戳缓存区域存放了对于查询结果相关的表进行插入, 更新或删除操作的时间戳. Hibernate 通过时间戳缓存区域来判断被缓存的查询结果是否过期, 其运行过程如下: T1 时刻执行查询操作, 把查询结果存放在 QueryCache 区域, 记录该区域的时间戳为 T1 T2 时刻对查询结果相关的表进行更新操作, Hibernate 把 T2 时刻存放在 UpdateTimestampCache 区域. T3 时刻执行查询结果前, 先比较 QueryCache 区域的时间戳和 UpdateTimestampCache 区域的时间戳, 若 T2 T1, 那么就丢弃原先存放在 QueryCache 区域的查询结果, 重新到数据库中查询数据, 再把结果存放到 QueryCache 区域; 若 T2 T1, 直接从 QueryCache 中获得查询结果,知识点15:时间戳缓存区域,32,二级缓存,知识点15:测试时间戳缓存区域,public void testUpdateTimeStampCache() Session session=sf.openSession(); Transaction tx=session.beginTransaction(); Customer c=(Customer)session.load(Customer.class, 1); System.out.println(c.getName(); Query query=session.createQuery(“update Customer c set c.name=张三 where c.id=1“); query.executeUpdate(); mit(); session.close(); session=sf.openSession(); tx=session.beginTransaction(); /重新查询数据库 c=(Customer)session.load(Customer.class, 1); System.out.println(c.getName(); mit(); session.close(); ,33,二级缓存,Query 接口的 iterator() 方法 同 list() 一样也能执行查询操作 list() 方法执行的 SQL 语句包含实体类对应的数据表的所有字段 Iterator() 方法执行的SQL 语句中仅包含实体类对应的数据表的 ID 字段 当遍历访问结果集时, 该方法先到 Session 缓存及二级缓存中查看是否存在特定 OID 的对象, 如果存在, 就直接返回该对象, 如果不存在该对象就通过相应的 SQL Select 语句到数据库中加载特定的实体对象 大多数情况下, 应考虑使用 list() 方法执行查询操作. iterator() 方法仅在满足以下条件的场合, 可以稍微提高查询性能: 要查询的数据表中包含大量字段 启用了二级缓存, 且二级缓存中可能已经包含了待查询的对象,知识点16: Query 接口的 iterator() 方法,34,二级缓存,知识点16: Query 接口的 iterator() 方法,/iterator 先到数据库中检索符合条件的id,让后根据id分别到一级和二级缓冲中查找对象 /(没有在查询数据库,每次只能查一个,可能导致n+1次查询 ) public void testIterator() Session session=sessionFactory.openSession(); Transaction tx=session.beginTransaction(); Query query=session.createQuery(“ from Order o where o.id it=query.iterate(); while(it.hasNext() System.out.println(it.next().getOrderNum(); mit(); session.close(); ,35,二级缓存,对于经常使用的查询语句, 如果启用了查询缓存, 当第一次执行查询语句时, Hibernate 会把查询结果存放在查询缓存中. 以后再次执行该查询语句时, 只需从缓存中获得查询结果, 从而提高查询性能 查询缓存使用于如下场合: 应用程序运行时经常使用查询语句 很少对与查询语句检索到的数据进行插入, 删除和更新操作 使用查询缓存的步骤 配置二级缓存, 因为查询缓存依赖于二级缓存 在 hibernate 配置文件中启用查询缓存 true 对于希望启用查询缓存的查询语句, 调用 Query 的 setCacheable(true) 方法,知识点17: 查询缓存,36,二级缓存,知识点17: 查询缓存,public void testQueryCache() Session session=sf.openSession(); Transaction tx=session.beginTransaction(); Query query=session.createQuery(“select c from Customer c where c.name=张三“); /* * 设置查询缓存 * * 如果查询缓存存在 直接返回 * * 如果查询缓存不存在 查询数据库 将查询结果防止到查询缓存中 */ query.setCacheable(true); query.list(); mit(); session.close(); session=sf.openSession(); tx=session.beginTransaction(); query=session.createQuery(“select c from Customer c where c.name=张三“); query.setCacheable(true); query.list(); mit(); session.close(); ,37,
展开阅读全文
相关资源
相关搜索

当前位置:首页 > 图纸设计 > 毕设全套


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!