一。什么时候会遇到1+N的问题?

前提:Hibernate默认表与表的关联方法是fetch="select",不是fetch="join",这都是为了懒加载而准备的。

1)一对多(<set><list>) ,在1的这方,通过1条sql查找得到了1个对象,由于关联的存在 ,那么又需要将这个对象关联的集合取出,所以合集数量是n还要发出n条sql,于是本来的1条sql查询变成了1 +n条 。

2)多对一<many-to-one>  ,在多的这方,通过1条sql查询得到了n个对象,由于关联的存在,也会将这n个对象对应的1 方的对象取出, 于是本来的1条sql查询变成了1 +n条 。

3)iterator 查询时,一定先去缓存中找(1条sql查集合,只查出ID),在没命中时,会再按ID到库中逐一查找, 产生1+n条SQL

二。怎么解决1+N 问题?

1 )lazy=true, hibernate3开始已经默认是lazy=true了;lazy=true时不会立刻查询关联对象,只有当需要关联对象(访问其属性,非id字段)时才会发生查询动作。

2)使用二级缓存, 二级缓存的应用将不怕1+N 问题,因为即使第一次查询很慢(未命中),以后查询直接缓存命中也是很快的。刚好又利用了1+N 。

3) 当然你也可以设定fetch="join",一次关联表全查出来,但失去了懒加载的特性。

三。示例

1.两张表

create table t_group (
id integer not null auto_increment,
name varchar(255),
primary key (id)
)

create table t_user (
id integer not null auto_increment,
name varchar(255),
myGroup integer,
primary key (id)
)

alter table t_user
  add index FKCB63CCB6D4A4BEC0 (myGroup),
  add constraint FKCB63CCB6D4A4BEC0
  foreign key (myGroup)
  references t_group (id)

2.代码如下:

@Entity
@Table(name="t_group")
public class Group {
private int id;
private String name; private Set<User> users = new HashSet<User>();
public Group(){ }
public Group(String name) {
this.name = name;
}
@Id
@GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@OneToMany(mappedBy="group")
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
}
@Entity
@Table(name="t_user")
public class User {
private int id;
private String name;
private Group group; public User(){ }
public User(String name) {
this.name = name;
} @ManyToOne
@JoinColumn(name="myGroup")
public Group getGroup() {
return group;
}
public void setGroup(Group group) {
this.group = group;
}
@Id
@GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

3.数据如下

4.默认情况下

    @Test
public void getAllUser(){
Session session = sf.openSession();
Transaction tx =session.beginTransaction();
List<User> groups = session.createQuery("from User").list(); //只要一条语句就可以取出全部内容。但hibernate默认会把关联的Group也取出来。
String string = "---------------------------- "; //由于每个user都不同group,所以会发出N条语句查询group.
                                        //本例会发出1+10条
for(User g : groups){
string += g.getName();
}
System.out.println(string);
tx.commit();
session.close();
}

5.解决:

(1).在User类中标注group----fetch=FetchType.LAZY

    @ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="myGroup")
public Group getGroup() {
return group;
}

(2).在Group类中写---------@BatchSize(size=10)

@Entity
@Table(name="t_group")
@BatchSize(size=10)
public class Group {}

(3)使用连接查询

List<User> groups = session.createQuery("from User u left join fetch u.group g").list();

注意:group是属性名,而不是数据库字段名。 不然出错

6.实验花絮:

    @Test
public void saveGroupAndUser2(){
Session session = sf.openSession();
Transaction tx =session.beginTransaction(); for(int i=1; i<=10; i++) {
Group g= new Group();
g.setName("g"+i);
session.save(g); User u = new User();
u.setName("u"+i);
u.setGroup(g);
session.save(u);
} tx.commit();
session.close();
}

参考下面的代码,上面红色字体的session.save(g)可以省略.不然org.hibernate.TransientObjectException: object references an unsaved transient instance

在User类中
@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name="myGroup")
public Group getGroup() {
return group;
}

hibernate注解(三)1+N问题的更多相关文章

  1. Hibernate注解映射联合主键的三种主要方式

    今天在做项目的时候,一个中间表没有主键,所有在创建实体的时候也未加组件,结果报以下错误: org.springframework.beans.factory.BeanCreationException ...

  2. Hibernate注解----类级别注解以及属性注解详解----图片版本

    这篇文章是我在慕课网上学习Hibernate注解的时候进行手机以及整理的笔记. 今天把它分享给大家,希望对大家有用.可以进行收藏,然后需要的时候进行对照一下即可.这样能起到一个查阅的作用. 本文主要讲 ...

  3. Hibernate注解配置

    在之前的第一次对框架的实际应用中,我使用的是Hibernate的xml配置方法,xml配置方法非常繁琐, 还是推荐所有使用Hibernate的人使用注解方式进行配置,在这篇文章中,我将列举出我们常用的 ...

  4. Hibernate注解使用以及Spring整合

    Hibernate注解使用以及Spring整合 原文转自:http://wanqiufeng.blog.51cto.com/409430/484739 (1) 简介: 在过去几年里,Hibernate ...

  5. 【maven + hibernate(注解) +spring +springMVC】 使用maven搭建项目

    研究,百度,查资料+好友帮助,使用MyEcplise2015工具,通过maven搭建hibernate+springMVC+spring的项目,数据库采用MySql5.5 不过使用的版本会在项目搭建过 ...

  6. [Hibernate] 注解映射例子

    Hibernate 注解(Hibernate Annotation) 是一种比较新的方式,通过在 java 简单类增加注解,来声明 java 类和数据库表的映射,作用和 xml 文件相似.hibern ...

  7. Hibernate注解与JPA

    Hibernate注解与JPA - charming的专栏 - CSDN博客http://blog.csdn.net/zxc123e/article/details/51499652 之前记录的一些东 ...

  8. Hibernate注解开发、注解创建索引

    1.注解的目的 简化繁琐的ORM映射文件(*.hbm)的配置 2.JPA和hibernate的关系 JPA:java persistence API,JPA注解是JavaEE的标准和规范. 两者的关系 ...

  9. hibernate 注解 联合主键映射

    联合主键用Hibernate注解映射方式主要有三种: 第一.将联合主键的字段单独放在一个类中,该类需要实现java.io.Serializable接口并重写equals和hascode,再将 该类注解 ...

  10. Hibernate学习一:Hibernate注解CascadeType

    http://zy19982004.iteye.com/blog/1721846 ———————————————————————————————————————————————————————— Hi ...

随机推荐

  1. Cesium添加水面

    var viewer = new Cesium.Viewer('cesiumContainer');var waterPrimitive = new Cesium.Primitive({ //show ...

  2. SVN设置没有写log不能commit

    操作方法:在SVN的Repositories下,找到要配置的项目,在项目目录下找到hooks文件夹,在其下创建pre-commit.bat文件,把下面复制进去就可以了(无需重启,如果改动,保存bat文 ...

  3. hadoop JOB的性能优化实践

    使用了几个月的hadoopMR,对遇到过的性能问题做点笔记,这里只涉及job的性能优化,没有接触到 hadoop集群,操作系统,任务调度策略这些方面的问题. hadoop MR在做大数据量分析时候有限 ...

  4. ldap命令

    ldapadd  -x   进行简单认证 -D   用来绑定服务器的DN -h   目录服务的地址 -w   绑定DN的密码 -f   使用ldif文件进行条目添加的文件 -W 交互式输入DN的密码 ...

  5. android基础---->IntentService的使用

    这一篇博客,我们开始前台服务与IntentServie源码分析的学习,关于service的生命周期及其简单使用,请参见我的博客:(android基础---->service的生命周期) 目录导航 ...

  6. Esper学习之十四:Pattern(一)

    1. Pattern Atoms and Pattern operatorsPattern是通过原子事件和操作符组合在一起构成模板.原子事件有3类,操作符有4类,具体如下: 原子事件:1). 普通事件 ...

  7. 云计算设计模式(二十一)——Sharding分片模式

    云计算设计模式(二十一)——Sharding分片模式 将一个数据存储到一组水平分区或碎片.存储和访问大量数据时,这个模式可以提高可扩展性. 背景和问题 由一个单一的服务器托管的数据存储区可能会受到以下 ...

  8. 学习 python 编写规范 pep8 的问题笔记

    决定开始Python之路了,利用业余时间,争取更深入学习Python.编程语言不是艺术,而是工作或者说是工具,所以整理并遵循一套编码规范是十分必要的.所以今天下午我根据PEP 8整理了一份,以后都照此 ...

  9. Makefile伪目标

    https://www.zybuluo.com/lishuhuakai/note/210174 本节我们讨论一个Makefile中的一个重要的特殊目标:伪目标. 伪目标是这样一个目标:它不代表一个真正 ...

  10. excel多个sheet表拆分成独立的excel文件

    一.问题: 公司做一个项目,给的用户上报文是一个包含多个sheet页的excel文件, 但是在实际处理报文数据的时候需要拆分excel文件为多个独立的报文excel文件 二.解决: (1)一个一个的复 ...