本文链接:http://www.orlion.ml/28/

一、保存

1、

假设一个group有多个user,一个user只属于一个group,当保存user对象到数据库中时可以

User u = new User();
u.setName("u1");
Group g = new Group();
g.setName("g1");
u.setGroup(g);
Session s = sessionFactory.getCurrentSession();
s.beginTransaction();
s.save(g);// 默认hibernate不会帮我们保存
s.save(u);
s.getTransaction().commit();

需要注意hibernate默认不会帮我们保存group对象,应该设置一下。

@ManyToOne有个属性cascade(级联),CascadeType它有

(1)ALL:所有的操作时对当前对象所有级联的对象都会被hibernate操作

(2)MERGE:调用merge()方法时(合并的时候)会进行级联 (MERGE=save+update)

(3)PERSIST:调用persist()方法时(存储的情况下)会进行级联

(4)PEFRESH: 当一个session从数据库中load了一个对象和它级联的对象到内存中,而另外一个session在数据库中对这个对象进行了修改,则hibernate会对第一个sesson load的对象级联的对象刷新操作 (A里面需要读B改过之后的数据)

(5)REMOVE: 删除的情况下会进行级联

(Cascade的属性指明做什么操作的时候关联对象是绑定在一起的)

测试:将User类的getGroup()方法上的@ManyToOne注解修改为@ManyToOne(cascade=(CascadeType.ALL)),然后注释掉上面代码块中s.save(g),运行程序可以发现group会被hibernate自动保存到数据库中。

2、

上面我们存user,关联的group hibernate会帮我们存进去,如果我们存group,关联的user会不会帮我们存进去呢?答:不会

User u1 = new User();
u1.setName("u1");
User u2 = new User();
u1.setName("u2");
User u3 = new User();
u1.setName("u3"); Group g = new Group();
g.setName("g1");
g.getUsers().add(u1);
g.getUsers().add(u2);
g.getUsers().add(u3); Session s = sessionFactory.getCurrentSession();
s.beginTransaction();
s.save(g);//这里如果不设置的话,u1,u2,u3不会自动帮我们存进去
s.getTransaction.commit();

如果想让hibernate帮我们存入group的关联对象需要设置一下:将Group类中的getUsers()方法上的注解@OneToMany(mappedBy="group")修改为@OneToMany(mappedBy="group",cascade=(CascadeType.ALL)),注:如果只这么设置的话,u1,u2,u3存入数据库中后group_id都为NULL,因为u1,u2,u3对象中的group属性是null,所以需要在代码块中加u1.setGroup(g);u2.setGroup(g);u3.setGroup(g)。

规律:(1)多对一关系从多的一方操作比较简单;(2)如果关联关系是双向的,则需要设好导航(mappedBy);(3)双向关系在程序中要设定双向关联

二、读

1、get方式

我们先从数据库中get一个User出来

Session s = sessionFactory.getCurrentSession();
s.beginTransaction();
// 当我们从数据库中将这个对象取出来的时候不管设不设cascade都会把关联的Group对象取出来
User u = (User)s.get(User.class , 1);
s.getTransaction().commit;

我们从数据库中get一个Group出来,不管设不设cascade不会把关联的user取出来,cascade只在存储的时候有效,读取需要再另外设置:

将Group类中的getUsers()方法上注解@OneToMany(mappedBy="group",cascade=(CascadeType.ALL))修改为:@OneToMany(mappedBy="group",cascade=(CascadeType.ALL),fetch=FetchType.EAGER),然后就可以在代码块中写:

Group g = (Group)s.get(Group.class,1);// 如果不加上fetch则不会将关联的User取出来
for(User u : g.getUsers()) {
System.out.println(u.getName());
}

User类中getGroup()方法上注解@ManyToOne默认FetchType是EAGER,因为

当我们从数据库中将这个user对象取出来的时候不管设不设cascade都会把关联的Group对象取出来

当我们将User类中注解@ManyToOne添加属性fetch=FetchType.LAZY时,当我们用到user关联的group时,才会取出来:

Session s = sessionFactory.getCurrentSession();
s.beginTransaction(); User u = (User)s.get(User.class , 1);// 这时不会取出group
System.out.println(u.getGroup().getName());// 这时会取出group s.getTransaction().commit; //System.out.println(u.getGroup().getName());这时会报错no session,原因是session已经关闭了。如果设置为EAGER则不会报错。

FetchType是个枚举类型,有:

(1)EAGER:(渴望)Define that data must be eagerly fetched

(2)LAZY:(懒惰)Define that data can be lazily fetched

2、load方式

三、更新

Session s = sessionFactory.getCurrentSession();
s.beginTransactio();
User u = (User)s.load(User.class , 1);
u.setName("user");
u.getGroup().setName("g");
s.getTransaction().commit();//会发出两条update语句

这样写可以但是我们通常更新的是处于游离状态的对象,而当user处于游离状态时session已经关闭了没法保存。

Session s = sessionFactory.getCurrentSession();
s.beginTransaction();
User u = (User)s.get(User.class,1); s.getTransaction().commit(); u.setName("user");
u.getGroup().setName("group"); Session s2 = sessionFactory.getCurrentSession();
s2.beginTransaction();
s2.update(u);
// 当User类中的getGroup()方法注解@ManyToOne添加属性cascade=CascadeType.ALL时,会更新group,否则当执行update方法时不会update Group
s2.getTransaction().commit();

四、删除

1、删除一个User

Session s = sessionFactory.getCurrentSession();
s.beginTransaction();
User u = (User)s.load(User.class,1);
s.delete(u);
// 这时候会把u删除,然后会把u关联的group对象关联的所有user删除
s.getTransaction().commit();

如果不想把group删除可以:

u.setGroup(null);
s.delete(u);

还可以使用HQL:

Session s = sessionFactory.getCurrentSession();
s.beginTransaction();
s.createQuery("delete from User u where u.id=1");
s.getTransaction().commit();

2、删除Group

Session s = sessionFactory.getCurrentSession();
s.beginTransaction();
Group g = (Group)s.load(Group.class,1);
s.delete(g);
// 这时候会把g删除会把g对象关联的所有user删除(当然已经设置了cascade=all)
s.getTransaction().commit();

如果不想删除所有user,可以把user的group_id设成null。

hibernate(十)双向关联关系的CRUD的更多相关文章

  1. Hibernate映射多对多双向关联关系(小案例)

    多对多双向关联关系(Project(工程)/Emp(员工)为案例): 步骤如下: 1.创建Project类,并需要定义集合类型的Emp属性 public class Project { //编号 pr ...

  2. Hibernate 一对多自身双向关联关系 用于类别表的实现

    分类:一对多自身双向关联关系 Java持久化类: package com.hyy.hibernate.one_to_many.domain; import java.util.HashSet; imp ...

  3. Hibernate关联关系的CRUD

    本文以Group和User(一对多.多对一)双向关联为例,介绍关联关系的CRUD   下面先介绍两个属性 cascade:只影响CRUD中的CUD,即存储(save).更新(update).删除(de ...

  4. Hibernate映射一对多双向关联关系及部门关联属性

    一对多双向关联关系:(Dept/Emp的案例) 既可以根据在查找部门时根据部门去找该部门下的所有员工,又能在检索员工时获取某个员工所属的部门. 步骤如下: 1.构建实体类(部门实体类加set员工集合) ...

  5. Hibernate中双向多对多的两种配置方式

    Hibernate中双向多对多的两种配置方式 1.建立多对多双向关联关系 package cn.happy.entitys; import java.util.HashSet; import java ...

  6. Hibernate一对一双向关联映射

    关键原因在于对象模型具有方向性: 单向:一端只能加载另一端,不能反过来. 双向:两端都可以加载另一端. 问题来了:如何我们想从身份证端(IdCard)加载人(Person),怎么办呢? 下面我们开始介 ...

  7. HIBERNATE一对一双向外键联合主键关联

    HIBERNATE一对一双向外键联合主键关联: 一. 创建主键类:这个主键必须实现serializedable接口和重写其中的hashCode方法和equals方法:为主键类添加一个叫做@Embedd ...

  8. hibernate和mybatis的之CRUD封装差别

    hibernate和mybatis的之CRUD封装差别 以下讲的是基于MVC三层架构. 由于设计架构的差别,hibernate在实际编程中可以把基础的CRUD封装,比如BaseDao类.其它类只要去继 ...

  9. Java进阶知识07 Hibernate一对一双向外键关联(Annotation+XML实现)

    1.Annotation 注解版 1.1.创建Husband类和Wife类 package com.shore.model; import javax.persistence.Entity; impo ...

随机推荐

  1. Object-C内存管理-对象引用计数的特例

    看到OC中内存管理这块,其中的引用计数部分,部分10.5上的EBOOK示例已经在10.9上不能运行正确了,比如下面的代码: NSString * str1 = @"string 1" ...

  2. matlab linux 安装

    1. 获取matlab的iso文件,并挂载到目录下2. sudo sh $(matlab_path)/matlab安装(破解,相关见说明)3. 加入系统路径,将$(matlab_install_pat ...

  3. Restore Oracle database to another server

    1. Copy or remotely mount the backupset folder from the source server to the target server 2. On the ...

  4. CocoaPods的版本升级

    我们在项目开发过程中为了更好的管理项目中引用的一些第三方的开源代码,我们在项目开发中都会使用CocoaPods,在项目中不使用Cocoapods可以绕过这篇帖子,但是Cocopods升级比较快,但是怎 ...

  5. halcon车牌的识别

    read_image (Audi2, 'audi2') fill_interlace (Audi2, ImageFilled, 'odd') dev_set_color('green') thresh ...

  6. springrain 1.1 发布,spring 的极简封装

    经过2个月的测试修改,springrain1.1已经稳定,今日发布. 主要改动如下: 1.添加批量更新和保存的方法 2.添加maven分支 3.添加博客管理的demo 4.增加redis做为缓存实现 ...

  7. 从为什么String=String谈到StringBuilder和StringBuffer

    前言 有这么一段代码: public class TestMain { public static void main(String[] args) { String str0 = "123 ...

  8. RabbitMQ(六)远程连接

    RabbitMQ(六)远程连接 默认情况下,rabbitmq使用`guest`来连接本地(localhost)的server,当需要远程连接时,就会失效. "guest" user ...

  9. 100天后 - 100-days-later

    赛斯·高汀(Seth Godin)的博客:  http://sethgodin.typepad.com/seths_blog/2013/04/100-days-later.html 面对着数以千计的图 ...

  10. [ZigBee] 2、 ZigBee开发环境搭建

    本节介绍ZigBee基本开发环境搭建,附件中有本节介绍的软件下载地址~ 链接:http://pan.baidu.com/s/1bLdqxg 1.IAR Embedded Workbench 的安装 S ...