观点:对于n+1问题的理解。

  一般而言说n+1意思是,无论在一对多还是多对一当查询出n条数据之后,每条数据会关联的查询1次他的关联对象,这就叫做n+1。

  但是我的理解是,本来所有信息可以一次性查询出来,也就是简单的连表查询,但是Hibernate会首先查询1次得到当前对象,然后当前对象里面的n个关联对象会再次访问数据库n次,这就是1+n问题。

  他们二者之间表达的意思其实是一样的,只是描述这个问题的角度不同。不过我认为1+n更准确,因为以前我第一次看到n+1问题的时候就总是在想是不是查n然后多出一次,那其实是没什么影响的,后来才明白。

  既然出现这个问题,肯定是要避免的,尤其是对于高并发的互联网应用,这种现象是绝对不允许出现的。

  Hibernate给出了3中解决方案,不过我个人比较偏向于手动写sql,也就是JDBC或者iBatis那种风格。因为这样的sql是绝对可控的,只是在移植性方面不如Hibernate。各有所长各有所短吧。

  下面是3中解决方案:

  1.延迟加载,当需要的时候才查询,不需要就不查询,但是感觉这种方式治标不治本,尤其是在那种报表统计查询的时候更为明显。

  2.fetch="join",默认是fetch="select",这个其实说白了就是一个做外连接,允许外键为空的情况之下。

  3.二级缓存,第一次查询之后存在内存中,后面的相同查询就快了。但是有2个缺点:a.二级缓存首先是有点浪费内存空间,如果多了的话浪费还比较严重,这是一个不好的方面,当然这不是主要的,主要的问题在于,二级缓存的特性决定的,那就是很少的增删改才做二级缓存,而对于普通的CRUD系统,其实不太适合。所以感觉也不是首选。

  综合来看,用外联结的方式比较好,Hibernate里面貌似叫什么迫切外联结,不知道他究竟有多迫切,非得取个这样的名字,不就是个关联查询嘛。

  参考:http://blog.163.com/weizonghua_2006/blog/static/13106065620124249412653/

Hibernate解决n+1问题的更多相关文章

  1. hibernate 解决并发问题

    hibernate 解决并发问题的策略有 1)设置hibernate事务隔离级别 2)hibernate中乐观锁的实现 ps:版本号是由hibernate自己维护的,我们自己只需要做以上二步即可实现乐 ...

  2. Hibernate解决高并发问题之:悲观锁 VS 乐观锁

    高并发问题是程序设计所必须要解决的问题,解决此类问题最主要的途径就是对对程序进行加锁控制.hibernate对加锁机制同样做出了实现,常用加锁方式为悲观锁和乐观锁.悲观锁指的是对数据被外界(包括本系统 ...

  3. hibernate 解决 java.lang.NoClassDefFoundError: Could not initialize class org.hibernate.validator.internal.engine.xxx 这类的问题

    <!-- 解决 java.lang.NoClassDefFoundError: Could not initialize class org.hibernate.validator.intern ...

  4. hibernate解决oracle的id自增?

    以前做SSH项目时,涉及到的数据库是mySQL,只需将bean的配置文件id设为native 就可以实现表id的自增. 现在用到了Oracle,当然知道这样是不行的啦,那么用序列自增? 我在网络上搜索 ...

  5. hibernate 解决诡异的mysql存入中文乱码

    使用hibernate查询mysql,通过bean的get方法拿到字符串再写入mysql中的字段会中文乱码,需要String string = xxx.get(),把get方法拿到的值传入到新的str ...

  6. hibernate 解决 java.lang.NoClassDefFoundError: org/hibernate/cfg/Configuration

    参考:https://stackoverflow.com/questions/9851528/java-lang-noclassdeffounderror-org-hibernate-cfg-conf ...

  7. hibernate 解决 org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1

    这是因为没有设置要更新的主键导致的,只要设置了要更新的主键就能更新成功(没有主键当然不能更新)

  8. Hibernate工作原理

    现在我们知道了一个概念Hibernate Session,只有处于Session管理下的POJO才具有持久化操作能力.当应用程序对于处于Session管理下的POJO实例执行操作时,Hibernate ...

  9. Hibernate框架—简介

    ORM对象/关系数据库映射 ORM全称Object/Relation Mapping,对象/关系数据库映射,可以理解成一种规范.该框架的基本特征:完成面向对象的编程语言到关系数据库之间的映射. ORM ...

随机推荐

  1. Android EditText 改变边框颜色

    第一步:为了更好的比较,准备两个一模一样的EditText(当Activity启动时,焦点会在第一个EditText上,如果你不希望这样只需要写一个高度和宽带为0的EditText即可避免,这里就不这 ...

  2. SQLAlchemy 对象缓存和刷新

    SQLAlchemy 对象缓存和刷新 SQLAlchemy 带有对象缓存机制,在重复查询相同的对象时,直接先查询本地的缓存,而不需要从数据库加载数据. 在每个 model 对象的内部,SQLAlche ...

  3. Android图片压缩方法总结

    本文总结Android应用开发中三种常见的图片压缩方法,分别是:质量压缩法.比例压缩法(根据路径获取图片并压缩)和比例压缩法(根据Bitmap图片压缩).   第一:质量压缩方法:   ? 1 2 3 ...

  4. LNMP 环境发布项目

    发布地址 /srv/www/wx 默认mysql 外部访问权限关闭,需开启 另:注意数据库没有导入,index.php会是空白 chmod -R 777 /var var的权限就变成777,var下的 ...

  5. 第二篇 Replication:分发服务器的作用

    本篇文章是SQL Server Replication系列的第二篇,详细内容请参考原文. 分发服务器是SQL Server复制的核心组件.分发服务器控制并执行数据从一个服务器移动到另一个服务器的进程. ...

  6. [NetTopologySuite](2)任意多边形求交

    任意多边形求交: private void btnPolygon_Click(object sender, EventArgs e) { , , , , , , , , , , , , , }; , ...

  7. mapreduce小结

    (不断更新) MapReduce架构是一种分布式编程架构,它本质上是将任务划分,然后归并.它是以数据为中心的编程架构,相比与分布式计算和并行计算等,它更看重的是吞吐率.它处理的数据是PB级的数据,它并 ...

  8. [c++基本语法]——构造函数初始化列表

    c++构造函数初始化成员变量列表: #pragma once class Node { public: int data; // 权值 Node *parent; // 父节点 Node *left; ...

  9. log4cxx安装和使用

    log4cxx是Java社区著名的log4j的c++移植版,用于为C++程序提供日志功能,以便开发者对目标程序进行调试和审计,log4cxx是apache软件基金会的开源项目,基于APR实现跨平台支持 ...

  10. JS语法部分

    定义变量使用通用类型var:字符串(需要引号),小数,整数,布尔型(只返回对或错),日期时间 算术运算符:+  —  *  /  %(1取余数,2判断是不是整数,3将某个数值变为某个范围之内的数,4判 ...