资源预览内容
第1页 / 共37页
第2页 / 共37页
第3页 / 共37页
第4页 / 共37页
第5页 / 共37页
第6页 / 共37页
第7页 / 共37页
第8页 / 共37页
第9页 / 共37页
第10页 / 共37页
亲,该文档总共37页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
hibernate第四天1知知识点一、点一、hibernate 二级缓存2使用C3P0连接池知识点1:配置c3p0连接池* 在在hibernate.cfg.xml文件中增加如下配置文件中增加如下配置org.hibernate.connection.C3P0ConnectionProvider 520120 3000true* 引入引入c3p0-0.9.1.jar3多个事多个事多个事多个事务务并并并并发发运行运行运行运行时时的并的并的并的并发问题发问题知识点2:概念4多个事多个事多个事多个事务务并并并并发发运行运行运行运行时时的并的并的并的并发问题发问题知识点2:案例5多个事多个事多个事多个事务务并并并并发发运行运行运行运行时时的并的并的并的并发问题发问题知识点2:丢失更新6多个事多个事多个事多个事务务并并并并发发运行运行运行运行时时的并的并的并的并发问题发问题知识点2:脏读7多个事多个事多个事多个事务务并并并并发发运行运行运行运行时时的并的并的并的并发问题发问题知识点2:虚读(幻读)8多个事多个事多个事多个事务务并并并并发发运行运行运行运行时时的并的并的并的并发问题发问题知识点2:不可重复读9Hibernate数据数据库级别的并的并发隔离级别隔离级别含义含义READ_UNCOMMITED允许你读取还未提交的改变了的数据。可能导致脏、幻、不可重复读READ_COMMITTED允许在并发事务已经提交后读取。可防止脏读,但幻读和 不可重复读仍可发生REPEATABLE_READ对相同字段的多次读取是一致的,除非数据被事务本身改变。可防止脏、不可重复读,但幻读仍可能发生。SERIALIZABLE完全服从ACID的隔离级别,确保不发生脏、幻、不可重复读。这在所有的隔离级别中是最慢的,它是典型的通过完全锁定在事务中涉及的数据表来完成的。知识点3: ANSI 事务隔离级别事务隔离级别ANSI SQL 标准定义了隔离级别,但并不是SQL数据库独有.JTA也定义了同样的隔离级别.级别越高,成本越高10Hibernate数据数据库级别的并的并发设置隔离置隔离级别每个数据库连接都有默认的隔离级别,通常是读已提交或可重复读.可以通过数据库配置设置,也可在应用程序中设置.例如Hibernate:hibernate.connection.isolation = 41Read uncommitted isolation2Read committed isolation4Repeatable read isolation8Serializable isolation注意:* Hibernate不可能改变在受管环境下由应用服务器提供的数据库连接 的隔离级别,只能通过改变应用服务器配置的方式来改变. * 设置隔离级别是全局选项,会影响所有的连接和事务.有时需要为某个特定 事务指定更多的限制. * Hibernate依赖于乐观的并发控制,使用版本检查和悲观锁实现附加的锁支 持.知识点3: ANSI 事务隔离级别事务隔离级别11管理管理管理管理sessionsession尽管让程序自主管理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:管理session12管理管理管理管理sessionsession如果把Hibernate 配置文件的hibernate.current_session_context_class 属性值设为thread, Hibernate 就会按照与本地线程绑定的方式来管理SessionHibernate 按以下规则把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管理管理管理管理sessionsession*在在hibernate.cfg.xml文件中增加文件中增加 thread*不是不是调用用sessionFactory.openSession().而是而是调用用sessionFactory. getCurrentSession().获取取session对象象.从当前的从当前的线程提取程提取session, * 当前线程如果存在session对象,取出直接使用 * 当前线程如果不存在session对象,获取一个新的session对象和当前的线程绑定 知识点4:在hibernate中如何配置14管理管理管理管理sessionsession范例代范例代范例代范例代码码15二二级缓存存缓存(Cache): 计算机领域非常通用的概念。它介于应用程序和永久性数据存储源(如硬盘上的文件或者数据库)之间,其作用是降低应用程序直接读写永久性数据存储源的频率,从而提高应用的运行性能。缓存中的数据是数据存储源中数据的拷贝。缓存的物理介质通常是内存知识点5:理解缓存定义16二二级缓存存Hibernate中提供了两个级别的缓存第一级别的缓存是 Session 级别的缓存,它是属于事务范围的缓存。这一级别的缓存由 hibernate 管理的,一般情况下无需进行干预第二级别的缓存是 SessionFactory 级别的缓存,它是属于进程范围的缓存SessionFactory 的缓存可以分为两类:内置缓存: Hibernate Hibernate 自带的自带的, , 不可卸载不可卸载. 通常在 Hibernate 的初始化阶段, Hibernate 会把映射元数据和预定义的 SQL 语句放到 SessionFactory 的缓存中, 映射元数据是映射文件中数据的复制, 而预定义 SQL 语句时 Hibernate 根据映射元数据推到出来的. 该内置缓存是只读的. 外置缓存外置缓存( (二级缓存二级缓存) ): 一个可配置的缓存插件一个可配置的缓存插件. 在默认情况下, SessionFactory 不会启用这个缓存插件. 外置缓存中的数据是数据库数据的复制, 外置缓存的物理介质可以是内存或硬盘知识点6:理解二级缓存定义17二二级缓存存知识点7:hibernate二级缓存的结构18二二级缓存存两个并发的事务同时访问持久层的缓存的相同数据时, 也有可能出现各类并发问题. 二级缓存可以设定以下 4 种类型的并发访问策略, 每一种访问策略对应一种事务隔离级别非严格读写(Nonstrict-read-write): 不保证缓存与数据库中数据的一致性. 提供 Read Uncommited 事务隔离级别, 对于极少被修改, 而且允许脏读的数据, 可以采用这种策略读写型读写型(Read-write):(Read-write): 提供 Read Commited 数据隔离级别.对于经常读但是很少被修改的数据, 可以采用这种隔离类型, 因为它可以防止脏读事务型(Transactional): 仅在受管理环境下适用. 它提供了 Repeatable Read 事务隔离级别. 对于经常读但是很少被修改的数据, 可以采用这种隔离类型, 因为它可以防止脏读和不可重复读只读型(Read-Only):提供 Serializable 数据隔离级别, 对于从来不会被修改的数据, 可以采用这种访问策略知识点8:理解二级缓存的并发访问策略19二二级缓存存适合放入二级缓存中的数据:很少被修改不是很重要的数据, 允许出现偶尔的并发问题不适合放入二级缓存中的数据:经常被修改财务数据, 绝对不允许出现并发问题与其他应用数据共享的数据知识点9:缓存中存放的数据20二二级缓存存Hibernate 的二级缓存是进程或集群范围内的缓存, 缓存中存放的是对象的散装散装数据二级缓存是可配置的的插件, Hibernate 允许选用以下类型的缓存插件:EHCacheEHCache: 可作为进程范围内的缓存, 存放数据的物理介质可以使内存或硬盘, 对 Hibernate 的查询缓存提供了支持OpenSymphony OSCache:可作为进程范围内的缓存, 存放数据的物理介质可以使内存或硬盘, 提供了丰富的缓存数据过期策略, 对 Hibernate 的查询缓存提供了支持SwarmCache: 可作为集群范围内的缓存, 但不支持 Hibernate 的查询缓存JBossCache:可作为集群范围内的缓存, 支持 Hibernate 的查询缓存4 种缓存插件支持的并发访问策略(x 代表支持, 空白代表不支持)知识点10:缓存提供的供应商21二二级缓存存1 1 拷拷贝ehcache-1.5.0.jarehcache-1.5.0.jar到当前工程的到当前工程的liblib目目录下下2 2 开启二开启二级缓存存 truetrue3 3 要指定要指定缓存的供存的供应商商 org.hibernate.cache.EhCacheProvider org.hibernate.cache.EhCacheProvider4 4 指定使用二指定使用二级缓存的存的类 * * 方法一方法一 在使用在使用类的的* *.hbm.xml.hbm.xml配置配置选择需要使用二级缓存的持久化类, 设置它的二级缓存的并发访问策略, 元素的cache 子元素表明Hibernate 会缓存对象的简单属性, 但不会缓存集合属性, 若希望缓存集合属性中的元素, 必须在 元素中加入 子元素知识点11_1:配置进程范围内的二级缓存(配置ehcache缓存)22二二级缓存存 * * 方法二方法二 在在hibernate.cfg.xmlhibernate.cfg.xml文件中配置文件中配置( (建建议) ) 5 配置ehcache默认的配置文件ehcache.xml(名字固定)(放在类路径下)知识点11_2:配置进程范围内的二级缓存(配置ehcache缓存)23二二级缓存存ehcache.xml文件文件知识点11:配置进程范围内的二级缓存(配置ehcache缓存)所有配置的二级缓存的默认使用的配置24二二级缓存存:指定一个目录, 当 EHCache 把数据写到硬盘上时, 将把数据写到这个文件目录下. 默认是C:WINDOWSTemp : 设置缓存的默认数据过期策略 设定具体的命名缓存的数据过期策略每个命名缓存代表一个缓存区域,每个缓存区域有各自的数据过期策略。命名缓存机制使得用户能够在每个类以及类的每个集合的粒度上设置数据过期策略。 知识点11:配置进程范围内的二级缓存(配置ehcache缓存)25二二级缓存存cachecache元素的属性元素的属性 name:name:设置置缓存的名字存的名字, ,它的取它的取值为类的全限定名或的全限定名或类的集合的名字的集合的名字 maxElementsInMemory :maxElementsInMemory :设置基于内存的置基于内存的缓存中可存放的存中可存放的对象最大数目象最大数目 eternal:eternal:设置置对象是否象是否为永久的永久的,true,true表示永不表示永不过期期, ,此此时将忽略将忽略timeToIdleSeconds timeToIdleSeconds 和和 timeToLiveSecondstimeToLiveSeconds属性属性; ; 默默认值是是false false timeToIdleSeconds:timeToIdleSeconds:设置置对象空象空闲最最长时间, ,以秒以秒为单位位, , 超超过这个个时间, ,对象象过期。当期。当对象象过期期时,EHCache,EHCache会把它从会把它从缓存中清除。如果此存中清除。如果此值为0,0,表示表示对象可以无限期地象可以无限期地处于空于空闲状状态。 timeToLiveSeconds:timeToLiveSeconds:设置置对象生存最象生存最长时间, ,超超过这个个时间, ,对象象过期。期。如果此如果此值为0,0,表示表示对象可以无限期地存在于象可以无限期地存在于缓存中存中. . 该属性属性值必必须大于或等大于或等于于 timeToIdleSeconds timeToIdleSeconds 属性属性值 overflowToDisk:overflowToDisk:设置基于内在的置基于内在的缓存中的存中的对象数目达到上限后象数目达到上限后, ,是否把溢出是否把溢出的的对象写到基于硬象写到基于硬盘的的缓存中存中 diskPersistent diskPersistent 当当jvmjvm结束束时是否持久化是否持久化对象象 true false true false 默默认是是falsefalsediskExpiryThreadIntervalSeconds diskExpiryThreadIntervalSeconds 指定指定专门用于清除用于清除过期期对象的象的监听听线程程的的轮询时间知识点11:配置进程范围内的二级缓存(配置ehcache缓存)26二二级缓存存 public void testCache() Session session=sf.openSession();Transaction tx=session.beginTransaction();Customer c c=(Customer)session.load(Customer.class, 1 1);System.out.println(c c.getNameName(); tx.commit(); session.close(); session=sf.openSession();tx=session.beginTransaction();c c=(Customer)session.load(Customer.class, 1 1);System.out.println(c c.getNameName();/cn.c3p0.Customer1225c6225c6System.out.println(c c); tx.commit(); session.close();知识点12:测试二级缓存和散列数据27二二级缓存存session=sf.openSession();tx=session.beginTransaction();c=(Customer)session.load(Customer.class, 1);System.out.println(c.getName();/cn.c3p0.Customer1353550System.out.println(c); /测试散列是重组的对象tx.commit(); session.close();知识点12:测试二级缓存和散列数据需要引入两个jar包在srping下能找到.libconcurrentbackport-util-concurrent.jar.libcommons-logging.jar28二二级缓存存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(张三);tx.commit();session.close();session=sf.openSession();tx=session.beginTransaction();c=(Customer)session.load(Customer.class, 1);System.out.println(customer.getName(); /张三tx.commit();session.close();知识点13:测试一级缓存更新数据会同步到二级缓存29二二级缓存存知识点14:测试二级缓存的数据存放到临时目录配置Order对象的缓存查看临时目录缓存中只能放10个对象30二二级缓存存知识点14:测试二级缓存的数据存放到临时目录/测试缓存溢出存放到临时目录Testpublic void testowerFlow() Session session=sf.openSession();Transaction tx=session.beginTransaction();Query query=session.createQuery( from Order o); /30个对象query.list().size();tx.commit();session.close();31二二级缓存存Hibernate 提供了和查询相关的缓存区域:时间戳缓存区域: org.hibernate.cahce.UpdateTimestampCache时间戳缓存区域存放了对于查询结果相关的表进行插入, 更新或删除操作的时间戳. Hibernate 通过时间戳缓存区域来判断被缓存的查询结果是否过期, 其运行过程如下:T1 时刻执行查询操作, 把查询结果存放在QueryCache 区域, 记录该区域的时间戳为T1T2 时刻对查询结果相关的表进行更新操作, 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(); tx.commit(); session.close(); session=sf.openSession();tx=session.beginTransaction();/重新查询数据库重新查询数据库c=(Customer)session.load(Customer.class, 1);System.out.println(c.getName(); tx.commit(); 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.id11);query.list().size();tx.commit();session.close(); session=sf.openSession();tx=session.beginTransaction();query=session.createQuery( from Order o);Iterator it=query.iterate();while(it.hasNext()System.out.println(it.next().getOrderNum();tx.commit();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();tx.commit();session.close(); session=sf.openSession();tx=session.beginTransaction();query=session.createQuery(select c from Customer c where c.name=张三);query.setCacheable(true);query.list();tx.commit();session.close();37
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号