hibernate优化措施


1.HQL多表操作:   fetch: 不能和单独条件的with一起使用
    ①交叉连接 :
    ②内连接:
        显示内连接 :
             无条件: from 类名 别名 inner join 类中对方的引用名, 得到list<object[]>,两个表各自的信息
              有条件: from 类名 别名 inner join 类中对方的引用名 with或where 类名.id = 2;
       隐式内连接 : from Order where Order.c.id = 1;
       迫切内连接 : select distinct 类名 from  类名 inner join fetch 类名.对方引用名  
                       结果是from后面的对象,结果会出现重复,需要去重

    ③外连接:
        左外连接 : from 类名 left outer join 类名.对方引用名;  得到的是数组;
        迫切左外连接连接 : select distinct 类名 from 类名 left outer join  fetch 类名.对方引用名;  得到对象
        右外连接

2. 事物管理:  原子性, 一致性, 隔离性, 持久性  脏读,  不可重复读(update),  幻读(虚读),(insert)
                    隔离级别:  read_uncommitted 读取未提交 ,  read_committed  : 解决脏读  repeatable_read: 解决不可重复读
                                    serialzable 串行化, 解决所有问题;不允许两个事物操作用一个目标数据

                    oracle : 默认是read_committed   mysql: 默认是repeatable_read

3. hibernate中设置事物隔离级别:
    在核心配置文件中: <property name=" hibernate.connection.isolation">可取值: 1 2 4 8
       1.读取未提交  2.解决脏读  4.解决不可重复读 8. 串行化, 解决所有问题

4. hibernate 提供了三种管理session的方式:
     ①session对象的生命周期与本地线程绑定(threadlocal),保证了在同一个线程获得同一个session
           1.在核心配置文件中,
               <property name="hibernate.current_session_context_class">thread
           2.使用getcurrentsession();
           3.注意事项: 在事物关闭或提交,session对象也会关闭,所以不用再次session.close();
    ②.session对象的生命周期与JTA事物绑定(分布式事物管理)
    ③hibernate委托程序来管理session的生命周期

5.HQL优化:
  1.使用参数绑定  2. 尽量少使用not  3.尽量使用where 来替换having  4.减少对表的查询
  5.使用表的别名   6.实体的更新与删除

6. 一级缓存优化 : 大批量更新操作,可能会出现异常; 这时候可能手动清除一级缓存.session.evict和session.clear

7.  延迟加载, 只有真正使用该对象的时候才会加载.提供程序性能.  只有load方法能体现出以下配置.

    ①类级别检索延迟加载:  a.  在映射文件中:  在 class标签中 lazy="true"    b. 注解 在类上面@proxy(lazy=true)
                                   如果将lazy设置false, 这时候load与get方法就一样了,都是立即检索.

    ②.关联级别检索: 查询到对象后,就能获得他的属性和方法,抓取策略

8.关于load和get方法使用时机, 处理大批量数据,用load
    如果用load只查询出来对象,不使用,直接把对象返回,就需要对一个延迟对象进行初始化,
            hibernate.initialize(对象的引用名);

9. 抓取策略;  指的是查找到某个对象后,通过这个对象去查询关联对象的信息时的一种策略

   可以在多对一或多对多的 :

      1. 在xml中:  set标签中或many-to-one, one-to-many
                         属性有 fetch主要描述是sql语句的格式, lazy:控制sql语句何时发送

      2. 在注解中: 在集合上, @Fetch() @lazycollection(),在many-to-one, one-to-many,@lazytoone();

      3.迫切左外连接和左外连接区别:

         迫切左外连接: left join fetch

             list()方法返回的集合中存放的是实体对象的引用,而且每个实体对象关联的对象也都会被初始化,

             因此也会存放所有关联对象的实体对象。

            需要注意的是: 查询结果中可能会有重复数据,需要通过LinkedHashSet包裹一下去重,

                                   然后再将其用HashSet包回原来类型。new ArrayList(new LinkedHashSet(目标对象))

         左外连接: left join

                  采用这种检索策略的话,list()方法返回的集合中存放的是对象数组类型。

     4.set上的fetch和lazy用于设置关联集合信息的抓取策略
          
            @Fetch()   1.select 多条简单的sql(默认)    2. join 迫切左外连接  3.subselect将生成子查询的sql
            @lazy      1.ture 延迟 (默认)    2.false 立即   3.extra 加强延迟(需要什么,就发送什么查询语句)

10. set上的fetch和lazy用于设置关联集合信息的抓取策略, 获取在一的一方如何查询多的一方.

    ①第一种组合: 会首先查询到客户信息,需要订单时候才会关联查询订单详情.

        @Fetch()   select 多条简单的sql
        @lazy      ture 延迟

    ②.第二种组合: 查询到客户信息,订单也会查询

         @Fetch()   select 多条简单的sql
          @lazy      false 立即

   ③.第三种组合: 查询到客户信息,订单不会查询出详细信息,当我们需要订单个数,只会统计个数,不会查询出订单详情
                          需要什么就会查询什么,不会多余查询.

           @Fetch()   select 多条简单的sql
           @lazy      extra 加强延迟

   ④第四种组合: lazy会失效,会使用立即查询.

       @Fetch()   join 迫切左外连接

       @lazy      1.ture 延迟 (默认)    2.false 立即   3.extra 加强延迟


   ⑤第五种组合: 会延迟查询,先查询出所有的客户id, 然后订单的in(客户的id) ,子查询

         @Fetch()   subselect将生成子查询的sql

         @lazy      ture 延迟

   ⑥第六种组合: 会立即查询,先查询出所有的客户id, 然后订单的in(客户的id) ,子查询

         @Fetch()   subselect将生成子查询的sql

         @lazy      false 立即


     ⑦.第七种组合: 会加强延迟查询,先查询出所有的客户id, 然后订单的in(客户的id) ,子查询

         @Fetch()   subselect将生成子查询的sql

         @lazy      extra 加强延迟


11. 在many-to-one, one-to-many, 在多的一方如何查询一的一方

      One的一方fetch与lazy;

     @fetch:    select 多条或一条简单的sql     join 迫切左外连接(默认值)

     @lazy      1.false 立即(默认值)  2.prox是否采用延迟,需要另一方类级别延迟策略来决定   3.no-proxy 不重要


12. 批量抓取 n+1问题

    我们在查询多个对象的关联对象时,可以采用批量抓取方式来对程序进行优化,

    在配置文件在set中或class中 batch-size属性来设置 , 底层就是where in(,,,)

    注解:  @Batchsize(size=数字)   


   注意: 一般在主表中设置.  如果要查子信息,在set上设置, 如果从子方来查询父方,也是在父方设置在<class>

   父与子区别: 有外键的称为子表,关联方也就是父表.

 

猜你喜欢

转载自blog.csdn.net/xc123_java/article/details/74091868