hibernate检索小结之——查询优化和延迟加载

Hibernate抓取(检索方式)

检索分为:立即检索和延迟检索

区别和原理:立即检索当(用户)请求一发立刻向数据库发送sql语句,不管该对象有没有被使用(访问去属性)。而延迟检索则是类似于保留查询,只有在该对象呗使用的时候才会想数据库发送sql语句,其实延迟检索返回的是目标类的代理子对象,没有向数据库发送任何请求,所有没有初始化,在断点模式下可以看见虽然该对象存在(有内存地址,不为null),但发现该你对象没有被初始化,只有当访问该对象的时候才会被初始化。当然还可以使用hibernate具类的initialize方法强制初始化代理对象,当访问对象的延迟加载时,底层也是调用Hibernate工具类的initialize方法

小结论:延迟加载提高效率(避免一些不必要的sql查询),而立即加载数据齐全(后续的查询可以直接到缓存里面查询)

抓取的策略:一方对多方,主表和重表的策略(主表查询的时候从表是否联动),多方对一方,重表和主表的策略(查询重表的时候是否联动主表),注意:这里的联动指的是向数据库立刻发送sql语句。

配置的含义:fetch表示立即加载,lazy表示延迟加载(懒加载)Fetch的值有两中,joinselectfetch的值为join的时候表示关联(以当前为主表左链接)查询,fetch的值为select的时候,非关联查询(只查询自己,不去查询关联的表),lazy的值有四种,tureflase,extra以及proxy(一些基本没意义的值就不提了).lazy的值为true表示延迟加载,false表示不延迟(立即加载).extra加强延迟加载(及其懒惰加载)proxy这个不确定要看依赖,当然这些只是相对的,具体还还看相互的搭配以及查询的方式。

小总结:fetchsql语句的生成方式(单表查询还是链表查询)lazy是数据初始化的时间(立即初始化还是访问其id外的属性的时候初始化),所以当fetchajoin的时候忽略lazy的值(因为链表查询肯定把关联数据查询出来了),当joinselect的时候(单表查询),此时lazy的值决定是否立即对关联数据进行检索。

配置与加载:一方(主表)默认的配置 fetch=join” lazy=true(链表查询和延迟加载。此时的延迟会被忽略)。所以如果查询当前对象的时候(默认配置),会立即和重表(多方)进行左链接查询,吧与之相关的数据全部查询出来。多方(重表)默认配置是fetch=”select” lazy=”proxy”(单表查询,延迟加载,但不确定),这个要看关联方的类加载(class 上配置的lazy 的属性)。当查询当前对象的时候不会立即加载所有的数据,因为是简单查询(单表),所以不会把与之关联的主表的数据查询出来,仅仅只显示当前数据。所有不做任何的配置(多方和一方都是默认配置), 查询一方的时候会默认吧多方数据关联出来,而查询多方则不会关联一方的数据。 如果(一方)采用默认配置,当查询一方(主表)的时候会连带吧多方(重表)的数据全部查询出来,而且数据信息大量重复,很多臃余的数据。而且有时候根本用不到重表(多方)的数据,这样影响了加载效率,并占用了内存,如果(多方)采用默认配置,查询当前对象的时候不会连带查询出主表的数据,仅仅只加载自己当前的数据,

小分析:都用默认配置(主表关联查询,立即加载(此时lazy被忽略),重表简单查询,延迟加载)。如果查询主表会有臃余的数据和占用内存,这样不好。而查询重表数据不齐全,而且还要频繁的向数据发送sql语句,这样也不好,所以默认配置查询主表和重表都不好

小推荐:主表配置,单表查询,延迟加载(fetch=select” lazy=true),从表配置:链表查询,立即加载(fetch=join” lazy=false),个人认为主表用单边查询和延迟加载,重表采用链表查询和立即加载。因为主表连带出的数据比较多(一方连带多方),所以单表比较好,说不定,数据根本用不到,而且再次查询的时候数据不会臃余,重表连带出的数据比较少(多方连带一方),每次查询值会连带一条数据,所以采用链表查询和立即加载,此时主表和重表都有数据,要用主表的数据时不必再向数据库发送请求。

查询与加载:凡事都有例外,以上的说法仅仅是针对get方式的查询(通过id查询),如果采用自定义查询语句,hql语句和sql语句,则fetch的值将会被忽略,是否延迟加载完全有lazy来决定,这个就比较简单了,如果是createQuery he createeSQLQuery方式的查询,lazy的值为ture,表示延迟加载,flase表示立即加载,extra加强延迟加载

顺带提一下,extra加强延迟加载的含义,意思是只有当访问其里面的po对象的id(主键)除外的属性才会被加载,例如:通过用户用户连带查询出来该用户的所有订单,当访问该订单的个数的时候都不加载该订单的数据,只有访问具体的某个订单的id除外的属性的时候(比如订单的金额)才会加载数据(加载该用户的所有订单不是加载一条订单),而一般的延迟加载则在访问其订单数量的时候加载该用户的所有订单,同样的如果返回一个list,如果访问list里面(po)对象的个数的事时候,不会加载,只有访问list里面的对象的属性(非主键属性)的时候才会被加载

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值