hibernate中get和load,find的区别

hibernate中get和load,find的区别,第1张

get和load方式是根据id取得一个记录

下边详细说一下get和load的不同,因为有些时候为了对比也会把find加进来。

1从返回结果上对比:

load方式检索不到的话会抛出orghibernateObjectNotFoundException异常

get方法检索不到的话会返回null

2从检索执行机制上对比: get方法和find方法都是直接从数据库中检索 而load方法的执行则比较复杂首先查找session的persistent Context中是否有缓存,如果有则直接返回 如果没有则判断是否是lazy,如果不是直接访问数据库检索,查到记录返回,查不到抛出异常 如果是lazy则需要建立代理对象,对象的initialized属性为false,target属性为null 在访问获得的代理对象的属性时,检索数据库,如果找到记录则把该记录的对象复制到代理对象的target上,并将initialized=true,如果找不到就抛出异常。

3根本区别说明

如果你使用load方法,hibernate认为该id对应的对象(数据库记录)在数据库中是一定存在的,所以它可以放心的使用,它可以放心的使用代理来 延迟加载该对象。在用到对象中的其他属性数据时才查询数据库,但是万一数据库中不存在该记录,那没办法,只能抛异常。所说的load方法抛异常是指在使用 该对象的数据时,数据库中不存在该数据时抛异常,而不是在创建这个对象时(注意:这就是由于“延迟加载”在作怪)。

由于session中的缓存对于hibernate来说是个相当廉价的资源,所以在load时会先查一下session缓存看看该id对应的对象是否存在,不存在则创建代理。所以如果你知道该id在数据库中一定有对应记录存在就可以使用load方法来实现延迟加载。

对于get方法,hibernate会确认一下该id对应的数据是否存在,首先在session缓存中查找,然后在二级缓存中查找,还没有就查数据库,数据库中没有就返回null。

对于load和get方法返回类型:虽然好多书中都这么说:“get()永远只返回实体类”,但实际上这是不正确的,get方法如果在 session缓存中找到了该id对应的对象,如果刚好该对象前面是被代理过的,如被load方法使用过,或者被其他关联对象延迟加载过,那么返回的还是 原先的代理对象,而不是实体类对象,如果该代理对象还没有加载实体数据(就是id以外的其他属性数据),那么它会查询二级缓存或者数据库来加载数据,但是 返回的还是代理对象,只不过已经加载了实体数据。

get方法首先查询session缓存,没有的话查询二级缓存,最后查询数据库;反而load方法创建时首先查询session缓存,没有就创建代理,实际使用数据时才查询二级缓存和数据库。

4简单总结

总之对于get和load的根本区别,一句话,hibernate对于load方法认为该数据在数据库中一定存在,可以放心的使用代理来延迟加载,如果在使用过程中发现了问题,只能抛异常;而对于get方法,hibernate一定要获取到真实的数据,否则返回null。

如果你正确开启了hibernate二级缓存,当然会保存在二级缓存里。

使用Statistics s=factorygetStatistics();//返回二级缓存的统计类对象,来检查是否二级缓存起作用,前提是你开启了getStatistics的功能,需要在配置文件中配置<prop key="hibernategenerate_statistics">true</prop>

二级缓存配置(spring+hibernate)

说明:本人不建议使用查询缓存,因为查询缓存要求完全相同的查询sql语句才会起作用,所说的查询缓存是针对第二次查询时 sql语句与第一次sql语句完全相同 那么就可以从缓存中取数据而不去数据库中取数据了,在不启用查询缓存的情况下 每次的查询数据也会缓存到二级缓存的 只不过每次查询都会去查询数据库(不包括根据ID查询),启用查询缓存很麻烦 需要每次查询时 调用QuerysetCacheable(true)方法才可以,如:List<OrgiData> orgiDatas = (List<OrgiData>) screateQuery("from OrgiData")setCacheable(true)list();

因此建议将查询缓存设置为如下:

hibernatecacheuse_query_cache=false

还有就是最重要的一点:对于经常修改或重要的数据不宜进行缓存,因为多并发时会造成数据不同步的情况。

首先增加ehcache-141jar和backport-util-concurrent-31jar或oscache-21jar

一、spring配置

<bean id="sessionFactory"

class="orgspringframeworkormhibernate3LocalSessionFactoryBean">

<property name="dataSource" ref="dataSource" />

<property name="mappingResources">

<list>

<value>com/handpay/core/merchant/bean/MerchGroupBuyhbmxml

</value>

</list>

</property>

<property name="hibernateProperties">

<value>

hibernatedialect=orghibernatedialectSQLServerDialect

hibernateshow_sql=true

hibernateformat_sql=true

hibernatehbm2ddlauto=update

hibernatecacheuse_second_level_cache=true

hibernatecacheuse_query_cache=false

hibernatecacheprovider_class=orghibernatecacheEhCacheProvider </value>

</property>

</bean>

<!---红色字体是二级缓存相关的设置->

二、hbmxml文件示例

<xml version="10">

<!DOCTYPE hibernate-mapping PUBLIC

"-//Hibernate/Hibernate Mapping DTD 30//EN"

">

根据你的情况,你的缓存对象在哪个内存,你所指的二级缓存就在哪个内存。你的对象在102

另hibernate只是在表象上对sql做了封装,底层还是用的sql进程crud,所以,如果跟你是否配置开启二级缓存有关。

合理的缓存应用可以极大地提高系统性能,最简单的是在应用层面做缓存(越高层面做缓存,效果往往越好),直接将数据缓存到服务器中,以全局map方式存储。在使用的时候直接从缓存的map中取,而不用连接数据库,从而提升性能。这种方式简单易行,但是map常驻服务器内存,并且在数据变更(增删改)的时候要手动更新map。还有一种方式比较通用,就是使用Hibernate二级缓存(SessionFactory级别的全局缓存,进程或集群级别),是一种通用缓存(一级缓存就不说了,Session级别缓存,hibernate自己管理),hibernate二级缓存多应用在多读少写的实体对象中,比如组织机构和系统字典。本文使用hibernate注解方式使用二级缓存,做一个说明(使用Ehcache)。1、添加ehcachexml配置文件2、hibernate配置文件中,配置Ehcache相关属性hibernatecacheuse_second_level_cache=truehibernatecacheuse_query_cache=truehibernatecacheprovider_class=orghibernatecacheEhCacheProviderhibernategenerate_statistics=true调试的时候,可以设置log4j的log4jloggerorghibernatecache=debug(记录二级缓存的活动),实际发布的时候,注释掉,以免影响性能。3、pom文件中引入相应jar包(Maven项目,如果还在手动添加jar包的,可以尝试使用maven)orghibernatehibernate-ehcache369Final4、注解方式配置实体配置了二级缓存后,并不是对所有的实体使用,而是需要指定哪些实体需要用到。如果不配置查询缓存(查询缓存会在下面讲到),则只会在根据id查询的 *** 作中,缓存对象。在实体上配置@Cache(usage=CacheConcurrencyStrategyNONSTRICT_READ_WRITE)并指定缓存并发策略。@Entity@Cache(usage=CacheConcurrencyStrategyNONSTRICT_READ_WRITE)@Table(name="base_dict")@JsonIgnoreProperties(value={"hibernateLazyInitializer","handler","fieldHandler","parentDict"})publicclassDictimplementsSerializable{//privatestaticfinallongserialVersionUID=5569761987303812150L;@Id@Column(name="id",length=36)@GeneratedValue(generator="uuid")@GenericGenerator(name="uuid",strategy="orghibernateidUUIDGenerator")@JsonProperty("id")privateStringid;/字典名称/@ForeignShow@Column(name="name",length=200)privateStringname;5、查询缓存的使用Queryquery=sessioncreateQuery(hql);querysetCacheable(true);//启用查询缓存querysetCacheRegion(“queryCacheRegion”);//设置查询缓存区域(数据过期策略)QueryCache只是在特定的条件下才会发挥作用,而且要求相当严格:(1)完全相同的HQL重复执行。(注意,只有hql)(2)重复执行期间,QueryCache对应的数据表不能有数据变动(比如添、删、改 *** 作)绝大多数的查询并不能从查询缓存中受益,所以Hibernate默认是不进行查询缓存的。查询缓存适用于以下场合:(1)在应用程序运行时经常使用的查询语句(参数相同)(2)很少对与查询语句检索到的数据进行插入、删除或更新 *** 作querylist();

Hibernate的缓存包括Session的缓存和SessionFactory的缓存,其中 SessionFactory的缓存又可以分为两类:内置缓存和外置缓存。Session的缓 存是内置的,不能被卸载,也被称为Hibernate的第一级缓存。 SessionFactory的内置缓存和Session的缓存在实现方式上比较相似,前者是 SessionFactory对象的一些集合属性包含的数据,后者是指Session的一些集 合属性包含的数据。SessionFactory的内置缓存中存放了映射元数据和预定义 SQL语句,映射元数据是映射文件中数据的拷贝,而预定义SQL语句是在 Hibernate初始化阶段根据映射元数据推导出来,SessionFactory的内置缓存 是只读的,应用程序不能修改缓存中的映射元数据和预定义SQL语句,因此 SessionFactory不需要进行内置缓存与映射文件的同步。SessionFactory的 外置缓存是一个可配置的插件。在默认情况下,SessionFactory不会启用这个 插件。外置缓存的数据是数据库数据的拷贝,外置缓存的介质可以是内存或者硬 盘。SessionFactory的外置缓存也被称为Hibernate的第二级缓存。

以上就是关于hibernate中get和load,find的区别全部的内容,包括:hibernate中get和load,find的区别、hibernate开启了二级缓存,session执行save *** 作把对象存进数据库,同时会把对象保存进二级缓存吗、hibernate二级缓存 和 spring整合的缓存(就是用哪个Cacheable注解的)有什么区别么等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/sjk/9502861.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-29
下一篇 2023-04-29

发表评论

登录后才能评论

评论列表(0条)

保存