ImageVerifierCode 换一换
格式:DOCX , 页数:8 ,大小:17.75KB ,
资源ID:3326679      下载积分:1 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bingdoc.com/d-3326679.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(135 Hibernate一级缓存.docx)为本站会员(b****1)主动上传,冰点文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰点文库(发送邮件至service@bingdoc.com或直接QQ联系客服),我们立即给予删除!

135 Hibernate一级缓存.docx

1、135 Hibernate一级缓存13.5Hibernate一级缓存缓存(Cache)是计算机领域非常通用的概念。它介于应用程序和永久性数据存储源(如硬盘上的文件或者数据库)之间,其作用是降低应用程序直接读写永久性数据存储源的频率,从而提高应用的运行性能。缓存中的数据是数据存储源中数据的副本,应用程序在运行时直接读写缓存中的数据,只在某些特定时刻按照缓存中的数据来同步更新数据存储源。技术要点正确使用缓存,可以大幅度提高系统的性能,但是错误使用缓存,反而会造成意想不到的结果,所以,理解Hibernate的缓存机制非常重要。Hibernate的缓存按照作用范围可以分为一级缓存和二级缓存,本节介绍一

2、级缓存。Hibernate的一级缓存是由Session提供的,因此它只存在于Session的生命周期中,当程序调用save()、update()、saveorupdate()等方法,及调用查询接口list、filter、iterate时,如session缓存中还不存在相应的对象,Hibernate会把该对象加入到一级缓存中,当Session关闭时,该Session所管理的一级缓存也会立即被清除。注意:Hibernate的一级缓存是Session所内置的,不能被卸载,也不能进行任何配置。一级缓存采用的是keyvalue的Map方式来实现的,在缓存实体对象时,对象的主关键字ID是Map的key,实

3、体对象就是对应的值。所以说,一级缓存是以实体对象为单位进行存储的,在访问时使用的是主关键字ID,虽然,Hibernate对一级缓存使用的是自动维护的功能,没有提供任何配置功能,但是可以通过Session中所提供的方法来对一级缓存的管理进行手工干预。本节代码演示Hibernate如下知识点:使用Hibernate一级缓存。了解Session使用缓存的常见方法。理解Session的load方法和get方法的区别。使用Log4j日志查看SQL执行情况。实现代码为了查看Hibernate如何访问数据库表,需要使用Log4j日志,读者可以将Hibernate安装包中projectetc目录下的log4j

4、.properties属性文件复制到项目路径中,默认的log4j.properties文件会造成大量的调试信息,这里对该属性文件进行了修改,只显示SQL访问信息,便于查看。log4j.properties文件内容代码如下:#定义标准输出#log4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.Target=System.outlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.

5、ConversionPattern=%dABSOLUTE%5p%c1:%L%m%n#定义日志文件hibernate.log#log4j.appender.file=org.apache.log4j.FileAppender#log4j.appender.file.File=hibernate.log#log4j.appender.file.layout=org.apache.log4j.PatternLayout#log4j.appender.file.layout.ConversionPattern=%dABSOLUTE%5p%c1:%L%m%n#设置日志优先级#log4j.rootLogg

6、er=warn, stdoutlog4j.rootLogger=debug, stdout#log4j.logger.org.hibernate=infolog4j.logger.org.hibernate=warn#log HQL query parser activity#log4j.logger.org.hibernate.hql.ast.AST=debug#log just the SQL显示SQL信息log4j.logger.org.hibernate.SQL=debug#log JDBC bind parameters#log4j.logger.org.hibernate.type

7、=infolog4j.logger.org.hibernate.type=warn#log schema export/update#log4j.logger.org.hibernate.tool.hbm2ddl=warn#log HQL parse treeslog4j.logger.org.hibernate.hql=debug#log cache activity#显示Hibernate缓存信息log4j.logger.org.hibernate.cache=debug#log transaction activitylog4j.logger.org.hibernate.transact

8、ion=warn#log JDBC resource acquisitionlog4j.logger.org.hibernate.jdbc=warn注意:Log4j的类库必须在CLASSPATH路径或者是项目的lib路径下,才能正常运行,默认的Hibernate类库已经包含了Log4j类库。增加1个Hibernate一级缓存的测试类:SessionCache.java,内容如下:package helloworld.session.test;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.h

9、ibernate.cfg.Configuration;public class SessionCachepublic static void main(Stringargs)/Configuration管理Hibernate配置Configuration config=new Configuration().configure();/根据Configuration建立SessionFactory/SessionFactory用来建立SessionSessionFactory sessionFactory=config.buildSessionFactory();/建立session,相当于建立

10、JDBC的ConnectionSession session=sessionFactory.openSession();/同一个session中建立2个实体对象Box box1=(Box)session.get(Box.class, new Integer(1);/box2使用了session缓存,并重新没有访问数据库Box box2=(Box)session.get(Box.class, new Integer(1);session.close();/session关闭,session缓存随即清除System.out.println(第一个session关闭);session=session

11、Factory.openSession();/重新建立sessionSystem.out.println(创建第二个session);box1=(Box)session.get(Box.class, new Integer(1);/重新访问数据库session.clear();/清除session缓存box2=(Box)session.get(Box.class, new Integer(1);session.close();sessionFactory.close();/关闭sessionFactory运行该示例,结果如下:14:12:42,734 DEBUG SQL:346select b

12、ox0.id as id00,box0.width as width00,box0.length aslength00,box0.height as height00,box0.name as name00from ssh.box box0where box0.id=?第一个session关闭创建第二个session14:12:42,796 DEBUG SQL:346select box0.id as id00,box0.width as width00,box0.length aslength00,box0.height as height00,box0.name as name00from

13、 ssh.box box0where box0.id=?14:12:42,843 DEBUG SQL:346select box0.id as id00,box0.width as width00,box0.length aslength00,box0.height as height00,box0.name as name00from ssh.box box0where box0.id=?上面测试代码获得对象使用了session的get方法,下面将get方法替换为load方法,测试类为SessionCacheLoad.java,内容如下:package helloworld.session.

14、test;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration;public class SessionCacheLoadpublic static void main(Stringargs)/Configuration管理Hibernate配置Configuration config=new Configuration().configure();/根据Configuration建立SessionFactory/SessionFactory

15、用来建立SessionSessionFactory sessionFactory=config.buildSessionFactory();/建立session,相当于建立JDBC的ConnectionSession session=sessionFactory.openSession();/同一个session中建立2个实体对象Box box1=(Box)session.get(Box.class, new Integer(1);System.out.println(第一个box);/box2使用了session缓存,并重新没有访问数据库Box box2=(Box)session.get(B

16、ox.class, new Integer(1);System.out.println(第二个box);session.close();/session关闭,session缓存随即清除session=sessionFactory.openSession();System.out.println(创建第二个session);box1=(Box)session.load(Box.class, new Integer(1);/重新访问数据库System.out.println(第一个box);box1.getName();box2=(Box)session.load(Box.class, new I

17、nteger(1);System.out.println(第二个box);box2.getName();session.close();sessionFactory.close();/关闭sessionFactory运行该测试程序,结果如下:14:25:04,750 DEBUG SQL:346select box0.id as id00,box0.width as width00,box0.length aslength00,box0.height as height00,box0.name as name00from ssh.box box0where box0.id=?第一个box第二个b

18、ox创建第二个session第一个box14:25:04,906 DEBUG SQL:346select box0.id as id00,box0.width as width00,box0.length as length00,box0.height as height00,box0.name as name00from ssh.box box0where box0.id=?第二个box源程序解读(1)为了查看Hibernate对数据库的访问情况,使用了Log4j日志,log4j.properties属性文件中,设置log4j.logger.org.hibernate.SQL=debug,即

19、可输出SQL语句信息,本例中,同时会输出hql和cache信息,但是本例并没有配置Hibernate的二级缓存,所以不会有cache信息输出。(2)第一个测试程序中的第一个session中,有2个ID都是1的box对象,从控制台的日志可以看到,这个session只访问一次数据库。第一个box对象的数据是从数据库中查询而来的,然后该对象就保存在session的缓存中,当第二个box对象调用get方法时,首先检查session缓存中是否有ID为1的对象,如果有,就从缓存中获得数据,并不会再次访问数据库。(3)第二个session中,不同的是加入了clear方法,即将session缓存数据清空,这样

20、在创建第二个box对象时,由于缓存中找不到该对象,则会再次使用SQL通过JDBC查询数据库获得数据。(4)第二个测试程序帮助我们来区分load和get方法之间的区别。(5)使用get方法获得持久化对象时,首先查找session缓存(Hibernate一级缓存)是否有该对象,如果有,则获得该对象;如果没有,就会访问数据库,如果数据库中找不到数据,则返回null。(6)load方法也是获得数据,但是不同的地方是load方法已经假定数据库中一定存在该数据的,如果在数据库中找不到该数据,则会抛出一个org.hibernate.ObjectNotFoundException异常。(7)load方法获得对象的过程:load方法首先在session缓存中查找对象,如果找不到则查找sessionfactory缓存(Hibernate二级缓存),如果再找不到则访问数据库。(8)值得注意的是,load方法是假定数据库中一定有该数据的,所以使用代理来延迟加载对象,只有在程序中使用到了该对象的属性(非主键属性)时,Hibernate才会进入load方法的获得对象过程。所以说,如果数据库中不存在该记录,异常是在程序访问该对象属性时抛出的,而不是在创建这个对象时就抛出。(9)第二个程序中的第二个session中可以看到,只有在访问box对象的name属性时才执行数据库查询的,而不是在创建box1时执行。

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2