`
forget丶兰
  • 浏览: 1972 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

hibernate 单双向N-1 1-N检索策略以及懒加载解决方案总结

 
阅读更多
 

  本例子表为 Students 表和Classes 表 其中 Students 表与Classes表的管理关系为单向N-1

单向N-1检索:
        在N的一方加入 lazy="false" ,即在做查询时 将与N关联的表全部查询出来(立即检索)

代码:

Students stu = (Students) session.get(Students.class, 1);
System.out.println(stu.getAddress());

 控制台显示的sql如下:

Hibernate: 
    select
        students0_.STUID as STUID1_1_0_,
        students0_.NAME as NAME2_1_0_,
        students0_.ADDRESS as ADDRESS3_1_0_,
        students0_.CLASSID as CLASSID4_1_0_ 
    from
        STUDENTS students0_ 
    where
        students0_.STUID=?
Hibernate: 
    select
        classes0_.CLASSID as CLASSID1_0_0_,
        classes0_.CLASSNAME as CLASSNAM2_0_0_ 
    from
        CLASSES classes0_ 
    where
        classes0_.CLASSID=?
wangzhe

 即我在只查询一个student的属性值时,它也将我的class表做了一个初始化,这种策略对于hibernate性能来说是很不好的。

懒加载问题:

    

Students stu = (Students) session.get(Students.class, 1);
System.out.println(stu.getAddress());
session.close(); //此处 session关闭
System.out.println(stu.getClasses().getClassName());

控制台sql:

    

Hibernate: 
    select
        students0_.STUID as STUID1_1_0_,
        students0_.NAME as NAME2_1_0_,
        students0_.ADDRESS as ADDRESS3_1_0_,
        students0_.CLASSID as CLASSID4_1_0_ 
    from
        STUDENTS students0_ 
    where
        students0_.STUID=?
Hibernate: 
    select
        classes0_.CLASSID as CLASSID1_0_0_,
        classes0_.CLASSNAME as CLASSNAM2_0_0_ 
    from
        CLASSES classes0_ 
    where
        classes0_.CLASSID=?
wangzhe
zhihuei

 由上可以看出:lazy=false 就是关闭掉了懒加载 ,所以这个是解决懒加载异常的策略之一,但是,这个策略却

极其消耗性能 。所以 我们一般在N的一方不去定义 lazy=false;顺便说一句 lazy="false"是没有懒加载异常的

 

单向N-1的检索策略:

               N-1  lazy ="proxy"(即单端N的一端默认的加载策略) 即生成代理 就是延时加载

代码如下:

         

	Students stu = (Students) session.get(Students.class, 1);
		System.out.println(stu.getAddress());

 控制台sql如下:

         

Hibernate: 
    select
        students0_.STUID as STUID1_1_0_,
        students0_.NAME as NAME2_1_0_,
        students0_.ADDRESS as ADDRESS3_1_0_,
        students0_.CLASSID as CLASSID4_1_0_ 
    from
        STUDENTS students0_ 
    where
        students0_.STUID=?
wangzhe

我们可以发现 .并没有初始化对应的classes 表 ,此时 classes对象的一个代理对象,

当session关闭时.代码如下:

Students stu = (Students) session.get(Students.class, 1);
		System.out.println(stu.getAddress());
		
		session.close(); //此处 session关闭
		System.out.println(stu.getClasses().getClassName());

会报一个懒加载异常  

懒加载异常解决办法如下:

典型应用:

          在hibernate 与spring整合时  有一张学生表与班级表 ,当我们要显示学生的的所有信息的时候用显示所有的班级名称,如果我们以默认的懒加载策略(lazy="proxy") 会报懒加载错误 ,因为此时班级对象是个代理(班级对象没有做初始化工作)而此时session却关闭了,所以会报 no -session........的懒加载异常。

那怎么解决呢?

                 有4种办法可以解决:

1.关闭懒加载(lazy=false)          就是 我在加载Student对象的时候就把classes对象的初始化工作完成,代码如上. 问题是这样极大的消耗我们的查询性能.所以不推荐 甚至这种办法应该舍弃掉。

2.在web.xml 里配置一个过滤器 ,即OpensessioninView 。    顾名思义 就是在渲染视图的时候session是一直开着的即当前事物方法结束之后 session 也一直开着 直到 视图渲染完成 。问题是,这会导致session混乱

在做高并发量小的项目时可以.但是高并发量就会导致不知预想的错误,所以 不推荐

3.改变抓取策略   我们在做本地sql的时候 会用到 left outer join  inner  jion等等一系列的连接查询

来查询出关联的表的数据 所有 我们可以在hql语句 定义一个left outer join 的连接查询

 代码如下:

 

FROM STUDENTS s LEFT OUTER JOIN FETCH s.classes;

也可以在N的一端的配置文件中指定抓取策略  即fetch="join"  但是我们一般不要在配置文件中去配置

 原因是 只要我们一查询 STUDENTS 表的属性时 它都会发出这样的左外连接语句.

4.在session关闭之前 就做一个初始化工作:

                如  Classes classes =Students的引用.getClasses();

                 但这个初始化工作视具体情况而定 .

                                                                      

单向多对一与双向多对一是一样的 。

单向1-N与双向1对多也是一样的 。只不过在单向或双向中 它的默认检索策略为 lazy="true"即开启懒加载。

分享到:
评论

相关推荐

    hibernate面试题2

    【hibernate面试题2】涉及了许多关于Hibernate框架的核心知识点,包括检索策略、SQL日志显示、缓存策略以及Hibernate与其他技术(如Spring和Struts)的整合。下面将逐一详细解析这些概念。 1. **Hibernate检索策略*...

    Hibernate电子书(全)

    此外,还需要下载Hibernate的最新稳定版本,例如3.0.1版,其中包含核心的`hibernate3.jar`文件以及一系列辅助的jar文件,如`cglib-2.1.jar`、`asm.jar`等,这些文件对于Hibernate的正常运行至关重要。 #### 第一个...

    Getting Started with Hibernate search

    依赖于Apache Lucene——一个强大的全文搜索引擎库,同时也是Java领域事实上的标准解决方案——Hibernate Search为Java开发者提供了一个强大且灵活的搜索解决方案。 ### 安装与配置 为了使用Hibernate Search,...

    hibernate入门

    **Hibernate** 是一款开源的对象关系映射(ORM)框架,它提供了强大的解决方案,用于处理Java应用中的数据持久化问题。对于初学者来说,理解Hibernate的基本概念和使用方法至关重要。 #### 二、准备工作 在开始...

    Spring,hibernate,struts的面试笔试题含答案

    3. **优秀的 ORM 实现:** Hibernate 是一种基于 JDBC 的主流持久化框架,提供了一种出色的 ORM(Object-Relational Mapping,对象关系映射)解决方案。 4. **透明性:** Hibernate 使用 Java 反射机制来实现透明性...

    SSH经典面试题目集合

    - 第三方缓存解决方案,如Ehcache等。 #### 5. Hibernate的查询方式 - **SQL查询**:直接使用SQL语句进行查询。 - **HQL(Hibernate Query Language)**:类似于SQL但更接近于面向对象的语言。 - 属性查询 - ...

    java面试题及答案-非常全面(包括基础、网络、数据结构、算法及IT大厂面经)

    - **解决方案**:使用工具(如VisualVM)检测并修复内存泄露。 - **OutOfMemoryError**:当Java堆空间不足时抛出。 ### for_each和for的效率差别 - **`for`循环**:通用循环结构,适用于任何类型的迭代。 - **`for...

    Hibernate

    在Java开发中,数据库操作通常是繁琐且容易出错的部分,而Hibernate通过提供对象关系映射(ORM)解决方案,将Java对象与数据库表之间的映射自动化,极大地提高了开发效率。Hibernate不仅处理了数据的存储和检索,还...

    黑马面试宝典知识点复习

    - **大数据量访问解决方案**:缓存策略、分库分表、读写分离等。 - **遇到的问题及解决办法**:技术难题、团队合作、时间管理等方面。 - **项目收获**:个人成长、团队协作经验等。 - **构建工具与模块划分**:构建...

    Java进阶路线

    - **Lucene, ElasticSearch, Solr, ELK**:流行的企业级搜索解决方案。 - **准确性, 召回率, 实时性**:评估搜索质量的关键指标。 - **禁词, 同义词, 直达, 分词**:提高搜索相关性的技术手段。 #### 十七、性能...

    Java EE 7 Recipes

    - 本章探讨了如何使用除Java之外的其他编程语言(如Groovy、Scala)来构建企业级解决方案。 - 这些语言通常与Java平台兼容,并且能够充分利用Java EE提供的功能。 - 了解这些替代语言可以帮助开发者选择最适合特定...

    JPA源文件/jpa学习

    JPA是Java EE和Java SE环境中的一种ORM(Object-Relational Mapping)解决方案,旨在替代Hibernate等第三方库,提供更加标准化的持久化框架。 **JPA规范**定义了应用程序与数据库交互的一组接口和API,包括实体...

    java面试问题汇总(非常全面)

    - **初始化**:当 Web 应用启动时,容器加载 Servlet 并调用其 `init()` 方法。 - **服务**:每次客户端请求 Servlet 时,容器调用其 `service()` 方法。 - **销毁**:当 Web 应用关闭时,容器调用 `destroy()` 方法...

Global site tag (gtag.js) - Google Analytics