仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 416|回复: 9
打印 上一主题 下一主题

[学习教程] 来看Hibernate进修(二)Hibernate中Session之get和load办法的真正区分

[复制链接]
小女巫 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-18 10:59:54 | 只看该作者 回帖奖励 |正序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
最后我再次声明,我并没有说不看好java,实际上我对java很乐观的,毕竟她正在不断改进中,我相信她总有一天会和.net并驾齐驱的
比来在进修SHH框架中的Hibernate,对Session的get和load办法,有点混不分明,不晓得区分在哪,大概对它们的区分感到不深。以是百度了一下,了局成绩来了。百度的了局和实践测试的了局收支很年夜。次要是对get办法的说法跟实践运转的了局纷歧致。
先说一下概念吧:
get不撑持lazy,load撑持lazy;
数据不存在时,get前往null,load则抛出ObjectNotFoundException非常。
load办法能够前往实体的代办署理类实例,而get办法间接读取数据库,以是间接前往实体类(get的这个说法是毛病的)
关于第一条,信任人人都没有太多的疑问。我这里给个例子稍作注释:lazy意味着用的时分才往实行sql语句。
Useruser=(User)session.load(User.class,"4028981b41174a690141174a6c6d0003");
这句代码不会往实行数据库查询,只要用到user时才会往实行数据库查询。以是不会当即天生sql语句。
Useruser=(User)session.get(User.class,"4028981b41174a690141174a6c6d0003");而下面这句代码则会当即往实行数据库查询(假如缓存中没有实例)。
尔后面的成绩要想申明白,起首得懂得一个成绩——Session加载实体对象的历程:
起首,Hibernate中保持了两级缓存。第一级缓存由Session实例保护,它是属于事件局限的缓存。个中坚持了Session以后一切联系关系实体的数据,也称为外部缓存。而第二级缓存则存在于SessionFactory条理,它是属于历程局限或聚集局限的缓存,由以后一切由本SessionFactory机关的Session实例共享。
出于功能思索,制止无谓的数据库会见,Session在挪用数据库查询功效之前,会先在缓存中举行查询。起首在第一级缓存(外部缓存)中,经由过程实体范例和id举行查找,假如第一级缓存查找射中,且数据形态正当,则间接前往。然后,Session会在以后“NonExists”纪录中举行查找,假如“NonExists”纪录中存在一样的查询前提,则前往null。“NonExists”纪录了以后Session实例在之前一切查询操纵中,未能查询到无效数据的查询前提(相称于一个查询黑名单列表)。云云一来,假如Session中一个有效的查询前提反复呈现,便可敏捷作出判别,从而取得最好的功能体现。
关于load办法而言,起首查找外部缓存,假如射中,则前往实例,假如外部缓存中未发明无效数据,则查询第二级缓存,假如第二级缓存射中,则前往。若二级缓存中仍旧未发明无效数据,则倡议数据库查询操纵(SelectSQL)。假如查询到,则前往实体类的代办署理对象,若经由查询未发明对应纪录,则将此次查询的信息在“NonExists”中加以纪录,并抛出ObjectNotFoundException非常。
关于get办法而言,很多书上、收集博客里都说错了。get办法一样是先查找外部缓存,假如射中,则前往,不然倡议数据库查询操纵,假如查询到,则前往实体类的对象,若经由查询未发明对应纪录,则将此次查询的信息在“NonExists”中加以纪录,并前往null。以是收集上说的“当别人修正了数据后,用load大概读取不到最新的数据,而get一定能够读取到最新修正的数据”的说法也是不建立的。
这也就意味着,get办法猎取到的其实不必定是实体类对象,load办法也纷歧定是前往实体代办署理类对象。
以上的概念都是我经由过程测试得出来的,有代码有图有原形呀:
  1. packagecom.bjpowernode.hibernate;
  2. importjava.util.Date;
  3. importjunit.framework.TestCase;
  4. importorg.hibernate.ObjectNotFoundException;
  5. importorg.hibernate.Session;
  6. importorg.hibernate.Transaction;
  7. /**
  8. *Session测试类
  9. *
  10. *@authorLongxuan
  11. *
  12. */
  13. publicclassSessionTestextendsTestCase{
  14. publicvoidtestEquals(){
  15. Sessionsession=null;
  16. try{
  17. //猎取Session
  18. session=HibernateUtils.getSession();
  19. //开启事件
  20. session.beginTransaction();
  21. System.out.println("
  22. ");
  23. try{
  24. //考证查不到数据时,get前往null,load抛ObjectNotFoundException非常
  25.                         //URL:http://www.bianceng.cn/Programming/Java/201410/45828.htm
  26. System.out.println(session.get(User.class,"123"));
  27. System.out.println(session.load(User.class,"123"));
  28. }catch(ObjectNotFoundExceptione){
  29. System.out.println("load办法抛出ObjectNotFoundException非常");
  30. }
  31. System.out.println("
  32. ");
  33. //考证load前往实体类对象,而非代办署理对象
  34. {
  35. Useruser1=(User)session.get(User.class,"4028981b41174a690141174a6c6d0003");
  36. Useruser2=(User)session.load(User.class,"4028981b41174a690141174a6c6d0003");
  37. System.out.println("user1:"+user1.getClass().getSimpleName());
  38. System.out.println("user2:"+user2.getClass().getSimpleName());
  39. System.out.println("user1与user2是不是为统一对象:"+user1.equals(user2));
  40. }
  41. System.out.println("
  42. ");
  43. session.clear();//扫除Session
  44. //考证get也能够前往代办署理类对象,而其实不必定前往实体类对象
  45. //同时考证了get办法先查找缓存(假如没有输入sql语句,则申明get查找了缓存)
  46. {
  47. Useruser3=(User)session.load(User.class,"4028981b41174a690141174a6c6d0003");
  48. Useruser4=(User)session.get(User.class,"4028981b41174a690141174a6c6d0003");
  49. System.out.println("user3:"+user3.getClass().getSimpleName());
  50. System.out.println("user4:"+user4.getClass().getSimpleName());
  51. System.out.println("user3与user4是不是为统一对象:"+user3.equals(user4));
  52. }
  53. session.getTransaction().commit();
  54. }catch(Exceptione){
  55. e.printStackTrace();
  56. session.getTransaction().rollback();
  57. }finally{
  58. HibernateUtils.closeSession(session);
  59. }
  60. }
  61. }
复制代码
运转了局图:

另有一个风趣的征象:
  1. Useruser5=(User)session.load(User.class,"123");
  2. System.out.println(user5.getId());
复制代码
运转了局间接输入123
从了局中也能够看出,前2句代码,不会往实行数据库操纵。由于load后会在hibernate的一级缓存里寄存一个map对象,该map的key就是Id的值,可是当你getId()时,它会往一级缓存里拿map的key值,恰好找到了,以是不会再往实行数据库查询。也不会报任何错。就有了以上的了局。

微软什么都提供了。你可以试想一下,如果你是新手,你是希望你点一下按钮程序就能运行那,还是想自己一点一点的组织结构,然后打包发部,调错再打包......
愤怒的大鸟 该用户已被删除
10#
发表于 2015-3-24 06:08:19 | 只看该作者
让你能够真正掌握接口或抽象类的应用,从而在原来的Java语言基础上跃进一步,更重要的是,设计模式反复向你强调一个宗旨:要让你的程序尽可能的可重用。
飘飘悠悠 该用户已被删除
9#
发表于 2015-3-17 09:34:22 | 只看该作者
是一种由美国SUN计算机公司(Sun Microsystems, Inc.)所研究而成的语言
海妖 该用户已被删除
8#
发表于 2015-3-10 20:03:21 | 只看该作者
不过,每次的执行编译后的字节码需要消耗一定的时间,这同时也在一定程度上降低了 Java 程序的运行效率。
乐观 该用户已被删除
7#
发表于 2015-3-1 16:51:16 | 只看该作者
吧,现在很流行的Structs就是它的一种实现方式,不过Structs用起来实在是很繁,我们只要学习其精髓即可,我们完全可以设计自己的MVC结构。然后你再研究一下软件Refactoring (重构)和极限XP编程,相信你又会上一个台阶。 做完这些,你不如整理一下你的Java代码,把那些经典的程序和常见的应用整理出来,再精心打造一番,提高其重用性和可扩展性。你再找几个志同道合的朋友成立一个工作室吧
再现理想 该用户已被删除
6#
发表于 2015-2-10 22:33:58 | 只看该作者
你快去找一份Java的编程工作来做吧(如果是在校学生可以去做兼职啊),在实践中提高自己,那才是最快的。不过你得祈祷在公司里碰到一个高手,而且他 还愿意不厌其烦地教你,这样好象有点难哦!还有一个办法就是读开放源码的程序了。我们知道开放源码大都出自高手,他们设计合理,考虑周到,再加上有广大的程序员参与,代码的价值自然是字字珠叽,铿锵有力(对不起,偶最近《金装四大才子》看多了)。
小女巫 该用户已被删除
5#
 楼主| 发表于 2015-2-4 23:01:17 | 只看该作者
你快去找一份Java的编程工作来做吧(如果是在校学生可以去做兼职啊),在实践中提高自己,那才是最快的。不过你得祈祷在公司里碰到一个高手,而且他 还愿意不厌其烦地教你,这样好象有点难哦!还有一个办法就是读开放源码的程序了。我们知道开放源码大都出自高手,他们设计合理,考虑周到,再加上有广大的程序员参与,代码的价值自然是字字珠叽,铿锵有力(对不起,偶最近《金装四大才子》看多了)。
蒙在股里 该用户已被删除
地板
发表于 2015-1-27 05:44:00 | 只看该作者
Java 不同于一般的编译执行计算机语言和解释执行计算机语言。它首先将源代码编译成二进制字节码(bytecode),然后依赖各种不同平台上的虚拟机来解释执行字节码。从而实现了“一次编译、到处执行”的跨平台特性。
admin 该用户已被删除
板凳
发表于 2015-1-22 08:30:14 | 只看该作者
是一种使用者不需花费很多时间学习的语言
简单生活 该用户已被删除
沙发
发表于 2015-1-19 21:48:24 | 只看该作者
自从Sun推出Java以来,就力图使之无所不包,所以Java发展到现在,按应用来分主要分为三大块:J2SE,J2ME和J2EE,这也就是Sun ONE(Open Net Environment)体系。J2SE就是Java2的标准版,主要用于桌面应用软件的编程;J2ME主要应用于嵌入是系统开发,如手机和PDA的编程;J2EE是Java2的企业版,主要用于分布式的网络程序的开发,如电子商务网站和ERP系统。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-9-22 14:41

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表