一般来说界面看起来卡是因为你取数据的时间太长了
你用timespan来看看每个过程耗时如何,才能知道到底如何优化
一般来说窗体第一次加载慢也是正常的,一个好的框架通常都会用到缓存,首次加载的时候会初始化缓存,这是比较费时间的
1 对于Hibernate get方法,Hibernate会确认一下该id对应的数据是否存在,首先在session缓存中查找,然后在二级缓存中查找,还没有就查询数据库,数据库中没有就返回null。这个相对比较简单,也没有太大的争议。主要要说明的一点就是在这个版本中get方法也会查找二级缓存!
2 Hibernate load方法加载实体对象的时候,根据映射文件上类级别的lazy属性的配置(默认为true),分情况讨论:
(1)
若为true,则首先在Session缓存中查找,看看该id对应的对象是否存在,不存在则使用延迟加载,返回实体的代理类对象(该代理类为实体类的子
类,由CGLIB动态生成)。等到具体使用该对象(除获取OID以外)的时候,再查询二级缓存和数据库,若仍没发现符合条件的记录,则会抛出一个
ObjectNotFoundException。
(2)若为false,就跟Hibernate get方法查找顺序一样,只是最终若没发现符合条件的记录,则会抛出一个ObjectNotFoundException。
这里get和load有两个重要区别:
如果未能发现符合条件的记录,Hibernate get方法返回null,而load方法会抛出一个ObjectNotFoundException。
load方法可返回没有加载实体数据的代理类实例,而get方法永远返回有实体数据的对象。(对于load和get方法返回类型:好多书中都说:“get
方法永远只返回实体类”,实际上并不正确,get方法如果在session缓存中找到了该id对应的对象,如果刚好该对象前面是被代理过的,如被load
方法使用过,或者被其他关联对象延迟加载过,那么返回的还是原先的代理对象,而不是实体类对象,如果该代理对象还没有加载实体数据(就是id以外的其他属
性数据),那么它会查询二级缓存或者数据库来加载数据,但是返回的还是代理对象,只不过已经加载了实体数据。)
总之对于get和load的根本区别,一句话,hibernate对于 load方法认为该数据在数据库中一定存在,可以放心的使用代理来延迟加载,如果在使用过程中发现了问题,只能抛异常;而对于get方法,hibernate一定要获取到真实的数据,否则返回null。
Session在加载实体对象时,将经过的过程:
首先,Hibernate中维持了两级缓存。第一级缓存由Session实例维护,其中保持了Session当前所有关联实体的数据,也称为内部缓存。而第二级缓存则存在于SessionFactory层次,由当前所有由本SessionFactory构造的Session实例共享。
出
于性能考虑,避免无谓的数据库访问,Session在调用数据库查询功能之前,会先在缓存中进行查询。首先在第一级缓存中,通过实体类型和id进行查找,
如果第一级缓存查找命中,且数据状态合法,则直接返回。之后,Session会在当前“NonExists”记录中进行查找,如果“NonExists”
记录中存在同样的查询条件,则返回null。“NonExists”记录了当前Session实例在之前所有查询 *** 作中,未能查询到有效数据的查询条件
(相当于一个查询黑名单列表)。
如此一来,如果Session中一个无效的查询条件重复出现,即可迅速作出判断,从而获得最佳的性能表现。对于load方
法而言,如果内部缓存中未发现有效数据,则查询第二级缓存,如果第二级缓存命中,则返回。如在缓存中未发现有效数据,则发起数据库查询 *** 作(Select
SQL),如经过查询未发现对应记录,则将此次查询的信息在“NonExists”中加以记录,并返回null。根据映射配置和Select
SQL得到的ResultSet,创建对应的数据对象。
将其数据对象纳入当前Session实体管理容器(一级缓存)。执行InterceptoronLoad方法(如果有对应的Interceptor)。
将数据对象纳入二级缓存。如果数据对象实现了LifeCycle接口,则调用数据对象的onLoad方法。 返回数据对象。
自己做一个小小的实验,明确一下load和get方法的工作原理。
首先get方法没有什么可说的,就是在Session执行此函数的时候hit一下数据库,而load方法比较麻烦,具体的执行流程是这样的:
java 代码
Session session=getSessionFactory()openSession();
Transaction tr=sessionbeginTransaction();
//Student stu2=(Student)sessionget(Studentclass, new Integer(5));
//if(sessioncontains(stu2)) Systemoutprintln("stu2 in the session");
Student stu=(Student)sessionload(Studentclass, new Integer(5));
stugetAddress();
trcommit();
sessionclose();
(1)
查找Session所在的persistent Context中是否有缓存的persistent
object,如果有则直接返回该persistent
object作为stu对象;如果没有,则需要建立代理对象,该代理对象不是我们认为的pojo,其中的代理对象的initialized属性为
false,target属性为null。
(2)在访问获得的代理对象的属性时,例如执行stugetArress()时,因为此时的persistent Context中没有该persistent object,所以会hit数据库。
(3)hit数据库时,如果在数据库中找到该对象对应的记录,那么用获得的对象赋值给该代理对象的target属性,并且将initialized属性改为true;如果在数据库中找不到该对象对应的记录,那么抛出orghibernateObjectNotFoundException异常。
而get方法每次执行都hit数据库,如果没有相对应的记录,那么就返回null。
以上就是关于c# 加载Load界面卡全部的内容,包括:c# 加载Load界面卡、Hibernate中get方法和load方法的区别、等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)