Hibernate【性能部分】

一。延迟加载。

为什么要使用延迟加载?

  

  对于需要数据的时候才加载这种方式,就是一种优化方式

Hibernate中的三种懒加载

(一)类的懒加载

   

    @Test
    public void testClass_Lazy(){
        SessionFactory sessionFactory=SessionFactoryUtils.getSessionFactory();
        Session session=sessionFactory.openSession();
        Privilege privilege=(Privilege)session.load(Privilege.class, 1); //没有发出sql语句
        privilege.getName();//真正加载属性的时候发出sql语句
        session.close();
    }

  

  看到此时的privilege对象是一个代理对象(javassist我们导入过这个jar包,知道该包是创立代理对象的。代理对象最后返回了一个Privilege类型对象,可知代理对象是目标类(Privilege类)的子类)

  结论:session.load(..)产生的是代理对象,该代理类是持久化类的子类。

(二)。集合的懒加载

    @Test
    public void testClass_Lazy2(){
        SessionFactory sessionFactory=SessionFactoryUtils.getSessionFactory();
        Session session=sessionFactory.openSession();
        Privilege privilege=(Privilege)session.get(Privilege.class, 2);
        Set<Person> persons=privilege.getPersons();
        for(Person p:persons){
            System.out.println(p.getName());
        }
        session.close();
    }

  说明:

    1.因为延迟加载在映射文件中,而映射文件一旦确定不能修改了

    2.延迟加载是通过 控制sql语句的发出时间来提高效率的

  •   many-to-one(单端关联)的懒加载

   根据多的一端加载一的一端

   为什么不详解这种多的一方加载一的一方呢?

     根据性能来说,没有什么影响,因为只有一条数据,所以怎么样都行


二。抓取策略

为什么需要用到抓取策略?

  问题:在查询一对多的关联关系对象时,如何查询效率最高!(Classes -> Student)

    方法一:查询Classes的记录数,然后根据查询出来数据再去Student找到相应的数据,依据(c.id=s.cid).所以造成了N+1条查询语句。N:classes的记录数 1:classes本身

    方法二:使用iterator().来查询也会造成N+1条查询语句

    方式三:修改抓取策略,查询只需要1+1条查询语句

  总结:抓取策略解决的问题的是,如何加载Set集合中数据的问题,发出怎样的sql语句,取加载载set集合的数据。

使用抓取策略

  因为抓取策略解决的是Set集合中数据的问题,所以在映射文件的set元素中,可以设置抓取策略,具体为

  第一步:设置映射文件中fetch属性

<set name="persons" cascade="save-update" fetch="join">
....
</set>

  fetch属性的值:

    join:左外连接:利用一条连接查询(一对多关系)两张表里的数据(ps:如果有子查询就不能用join了,此时就变成了select)

    (默认)select:先查询一的一方的所有对象,再根据每一个对象的id值查询关联对象

    subselect:支持子查询  

  

  第二步:依旧采取上面方法一与方法二的查询方法,观察后台发出的sql语句

Hibernate:

select

students0_.cID as cID0_1_,

students0_.ID as ID1_,

students0_.ID as ID1_0_,

students0_.NAME as NAME1_0_

from

STUDENT students0_

where

students0_.cID in (

select

classes0_.ID

from

CLASSES classes0_

)

      这样的子查询就提高了效率

说明:

  1.因为抓取策略设置在映射文件中,所以一旦映射文件生成就不能修改了

  2.通过发出怎么样的sql语句加载集合,从而提高效率

Hibernate支持三种查询:
1.HQL语句

2.条件(criteria)查询

  类的拼接,查看hibernate源文档

3.sql查询

时间: 2024-10-25 06:10:57

Hibernate【性能部分】的相关文章

如何进行HIBERNATE性能调优

大体上,对于HIBERNATE性能调优的主要考虑点如下: ? 数据库设计调整 ? HQL优化 ? API的正确使用(如根据不同的业务类型选用不同的集合及查询API) ? 主配置参数(日志,查询缓存,fetch_size, batch_size等) ? 映射文件优化(ID生成策略,二级缓存,延迟加载,关联优化) ? 一级缓存的管理 ? 针对二级缓存,还有许多特有的策略 ? 事务控制策略. 1. 数据库设计 a) 降低关联的复杂性 b) 尽量不使用联合主键 c) ID的生成机制,不同的数据库所提供的

Hibernate性能优化之EHCache缓存

像Hibernate这种ORM框架,相较于JDBC操作,需要有更复杂的机制来实现映射.对象状态管理等,因此在性能和效率上有一定的损耗. 在保证避免映射产生低效的SQL操作外,缓存是提升Hibernate的关键之一. 加入缓存可以避免数据库调用带来的连接创建与销毁.数据打包拆包.SQL执行.网络传输,良好的缓存机制和合理的缓存模式能带来性能的极大提升,EHCache就提供了这种良好的缓存机制. 在考虑给系统加入缓存进行优化前,复用SessionFactory是Hibernate优化最优先.最基础的

Hibernate 性能优化及缓存的使用

1 clear()方法的运用: 由于hibernate在查询出来数据之后,会把数据进行缓存,对于同一个session多次大数据的查询,由于缓存会占用一定的内存空间,因此要多用seesion.clear(0方法清空缓存: 2 对于多发的sql语句合理设置tetch: 在关联查询时候,有时候只查询其中一个表里的数据,而hibernate会发出多条sql语句把另外一张表的数据也进行查询,影响性能,可以通过设置fetch的值来进行关联查询时候的懒加载:例如在多对一查询时候 @ManyToOne(casc

第七章 Hibernate性能优化

一对一关联 实体类关系 一对多 多对多 一对一 Hibernate提供了两种映射一对一关联关系的方式:按照外键映射和按照主键映射.下面以员工账号和员工档案表为例,介绍这两种映射方式,并使用这两种映射方式分别完成以下持久化操作: (1)保存员工档案的同时分配给员工一个账号. (2)加载员工档案的同时加载账号信息. 1.按照外键映射 步骤一:创建实体类Users1和Resume1 Users1创建如下: public class Users1 { private Integer userid; pr

Hibernate性能优化之SessionFactory重用

Hibernate优化的方式有很多,如缓存.延迟加载以及与SQL合理映射,通过对SessionFactory使用的优化是最基础的. SessionFactory负责创建Session实例,Session相当于JDBC里的Connection. SessionFactory的创建 SessionFactory是通过Configuration来构建的,Configuration会根据配置信息来构建SessionFactory. SessionFactory中保存了对应当前数据库配置的所有映射关系,还

Hibernate性能优化

性能优化 1.Session.clear()的应用 不断分页循环的时候,使用clear()方法. Java中的内存泄漏: 如果使用java打开某一个资源后,一定要关闭,否则就有可能导致内存泄漏.比如:使用java打开一个文件,实际上是java调用了C,C调用了windows底层的API,如果不手动将资源关闭,C语言必须手动回收内存,这就导致了有java引起的内存泄漏. 2.1+N问题 (1)使用@ManyToOne的时候,默认FetchType=EAGER,此时会自动取出One这一方的信息. (

8.Hibernate性能优化

性能优化 1.注意session.clear() 的运用,尤其在不断分页的时候 a) 在一个大集合中进行遍历,遍历msg,取出其中额含有敏感字样的对象 b) 另外一种形式的内存泄漏( //面试题:Java有内存泄漏吗?语法级别没有,但是可由java引起,例如:连接池不关闭,或io读取后不关闭) 2.1+N 问题(典型的面试题) 举例:当存在多对一关系时,多的一方默认是可以取出一的一方的 @ManyToOne 中 默认为fetch=FetchType.Eager 当load多的一方时,也会加载一的

Hibernate 性能优化之抓取策略

fetch 抓取策略 前提条件:必须是一个对象操作其关联对象. 1. 根据一的一方加载多的一方,在一的一方集合中,有三个值:join/select/subselect 2.根据多的一方加载一的一方, 这种情况不考虑,因为关联对象就一个数据,怎么样都可以join 连接  [一次性的把两张表的数据全部查询出来,只发出一条sql语句]    *  在页面上既包括一的一方的数据,又包括多的一方的数据    *  数据库的数据量比较小select 默认的查询方式    [先加载classes,当得到stu

Hibernate 性能优化之懒加载

针对数据库中的大数据,不希望特别早的加载到内存中,当用到它的时候才加载 懒加载分为:类的懒加载.集合的懒加载.单端关联的懒加载 类的懒加载    1.在默认情况下,类就是执行懒加载        2.只有使用了load方法以后才能用懒加载    3.如果在相应的映射文件中,设置<class>的lazy="false"懒加载将失去效果集合的懒加载     1.针对一多对的情况或者多对多的情况    2.根据一方加载set集合,决定在什么时候给set集合填充数据        

Hibernate 性能优化之查询缓存

查询缓存是建立在二级缓存基础之上的,所以与二级缓存特性相似,是共享的,适合修改不是很频繁的数据 查询缓存不是默认开启的,需要设置      1.在cfg文件中配置 <property name="cache.use_query_cache">true</property> 2.在代码中进行设置 query.setCacheable(true);