hibernate关联映射(一对多)

这篇博客将会给大家带来hibernate的关联映射的学习。在现实生活中,不仅只是一对一的映射关系,更多的是一对多,多对多等。

一对多单项关联映射

这里我以网盘为例,一个用户可以拥有多个文件,及用户和文件之间是一对多的关系。

user实体类:

public class Users {

    private int uid;
    private String uname;

    //用户上传的所有文件 // one方 可以获取  many方
    private Set<UpFile> files = new HashSet<UpFile>();

    public Users() {
        super();
        // TODO Auto-generated constructor stub
    }
    public Users(int uid, String uname) {
        super();
        this.uid = uid;
        this.uname = uname;
    }

    public int getUid() {
        return uid;
    }

    public void setUid(int uid) {
        this.uid = uid;
    }

    public String getUname() {
        return uname;
    }

    public void setUname(String uname) {
        this.uname = uname;
    }

    public Set<UpFile> getFiles() {
        return files;
    }

    public void setFiles(Set<UpFile> files) {
        this.files = files;
    }
}

UpFile实体类如下:

public class UpFile {

    private int fid;
    private String fileName;
    private int fsize;

    public UpFile() {
        super();
        // TODO Auto-generated constructor stub
    }

    public UpFile(int fid, String fileName, int fsize) {
        super();
        this.fid = fid;
        this.fileName = fileName;
        this.fsize = fsize;
    }
    public int getFid() {
        return fid;
    }

    public void setFid(int fid) {
        this.fid = fid;
    }

    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }
    public int getFsize() {
        return fsize;
    }
    public void setFsize(int fsize) {
        this.fsize = fsize;
    }
}

可以看到,一对多的设置只是在一方通过set集合来实现的,因为set集合是不能重复的,所以使用它。

Users.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="a.b.c.Users">
        <id name="uid">
            <generator class="native"/>
        </id>
        <property name="uname"/>
        <!-- one-to-many -->
        <set name="files">
            <key column="u_id"/>
            <one-to-many class="a.b.c.UpFile"/>
        </set>
    </class>
</hibernate-mapping>  

UpFile.hbm.xml

<hibernate-mapping>
    <class name="a.b.c.UpFile">
        <id name="fid">
            <generator class="native"/>
        </id>
        <property name="fileName"/>
        <property name="fsize"/>
    </class>
</hibernate-mapping>

通过<set></set> 标签实现的一对多关系。对于user表的主键作为upfile表的外键。

此时,执行一条插入操作:

session.beginTransaction();
Users u = new Users(0,"赵六");
UpFile f = new UpFile(0,"ccc.txt",453);
UpFile f2 = new UpFile(1,"bbb.txt",500);
u.getFiles().add(f);    //one端集合关系
u.getFiles().add(f2);
session.save(f);
session.save(f2);
session.save(u);

此时控制台打印的sql语句如下:

可以看到hibernate是首先插入所有的多方,然后利用update来更新一对多的关系。

可以看到在upfile中,有一个u_id作为外键。

一对多级联操作

在上面的一对多的插入操作当中,首先插入了两个UpFile,然后插入单个user,其实不必这么麻烦,可以配置级联操作:

<set name="files" cascade="all">
    <key column="u_id"/>
    <one-to-many class="a.b.c.UpFile"/>
</set>

cascade=”all”这里,我配置值为all,表示基于user的所有操作都会关联到和其关联的UpFile表的数据,cascade有如下一些值:

delete,

update,

all,

none

在配置了级联操作以后,执行插入就可以只插入User了,hibernate会将和该user关联的所有upfile都进行添加操作:

session.beginTransaction();
Users u = new Users();
u.setUname("adsf");
UpFile f = new UpFile("ccc.txt",453);
UpFile f2 = new UpFile("bbb.txt",500);
u.getFiles().add(f);    //one端集合关系
u.getFiles().add(f2);
session.save(u);
session.getTransaction().commit();  

一对多关联延迟加载

<set name="files" cascade="all" lazy="false">
    <key column="u_id"/>
    <one-to-many class="a.b.c.UpFile"/>
</set>

如果配置lazy=”false”表示立即加载。此时只要查询每一个user的时候,都会将该user对应的upfile查询出来,如果lazy=”true”,那么当查询user的时候,不会立即将该user对应的upfile查询出来,而是在使用到的时候,才根据该user的主键去upfile表中查找。

删除一对多关联

Configuration cfg = new Configuration().configure();
SessionFactory factory = cfg.buildSessionFactory();
Session session = factory.openSession();
Transaction transaction = session.beginTransaction();
Users u1  = (Users)session.get(Users.class, 1);
UpFile upFile = (UpFile) session.get(UpFile.class,2);
u1.getFiles().remove(upFile);
transaction.commit();
session.close();                

此时,所有的数据都还继续存在,只是将关联删除。

一对多双向关联

之前关于user和upfile的一对多的关联是单向的,也就是说我们只能通过user来获得和操作upfile,反过来则是不行的,那么怎么配置”一对多的双向关联”??

1.需要在Upfile类中增加user属性,并为该属性提供get和set方法

private Users users;

2.配置映射文件:

Users.hbm.xml

<hibernate-mapping>
    <class name="a.b.c.Users">
        <id name="uid">
            <generator class="increment"/>
        </id>
        <property name="uname"/>
        <!-- one-to-many -->
        <set name="files" cascade="all">
            <key column="u_id"/>
            <one-to-many class="a.b.c.UpFile"/>
        </set>
    </class>
</hibernate-mapping>  

Upfile.hbm.xml

<hibernate-mapping>
    <class name="a.b.c.UpFile">
        <id name="fid">
            <generator class="increment"/>
        </id>
        <property name="fileName"/>
        <property name="fsize"/>
        <many-to-one name="users" column="u_id" cascade="all"></many-to-one>
    </class>
</hibernate-mapping>    

此时如果从多的一端来维护数据,比如我在这里插入为uid=1的user插入在关联一个upfile文件:

Configuration cfg = new Configuration().configure();
SessionFactory factory = cfg.buildSessionFactory();
Session session = factory.openSession();
try {
    session.beginTransaction();
    Users u = (Users) session.get(Users.class,1);
    UpFile f = new UpFile("fff.txt",453);
    UpFile f2 = new UpFile("ttt.txt",500);
    f.setUsers(u);
    f2.setUsers(u);
    session.save(f);
    session.save(f2);
    session.getTransaction().commit();
} catch (HibernateException e) {
    e.printStackTrace();
    session.getTransaction().rollback();
}
session.close();

可以看到,这个时候就是通过f2.setUsers(u);这样的方式来建立关联的。存入数据也是存入的多端数据即可。

此时对于一对多的双向关联,一的一端和多的一端都可以同时维护数据,那么如果我只想让多的一端来维护数据,可以添加一个inverse=”true”这个关键字。

<set name="files" cascade="all" inverse="true">
    <key column="u_id"/>
    <one-to-many class="a.b.c.UpFile"/>
</set>

好了,关于hibernate一对多的学习就到这里了。

时间: 2024-10-12 01:42:00

hibernate关联映射(一对多)的相关文章

第六章 Hibernate关联映射

第六章 hibernate关联映射一.本章知识点分为2部分:1.关联关系:单向多对一关联关系,双向一对多关联关系(含一对多关联关系),多对多关联关系2.延迟加载:类级别加载策略,一对多加载策略,多对一加载策略二.关联关系1.单向多对一关联关系1.1.概念(什么是单向多对一关联关系,举例说明)  以部门(Dept).Emp(员工)为例: 从员工角度看部门,是多个员工都在一个部门,这就叫单向 如部门编号为20的部门下可以有n个员工(如scott账户下emp表 empno 为7369,7566,778

Hibernate关联映射(单项多对一和一对多、双向一对多)

最近总是接触着新的知识点来扩展自己的知识面:不停的让自己在原地接触天空的感觉真的很美好!!!革命没有成功,程序员的我们怎么能不努力呢...... 一.用员工和部门来剖析关联映射的原理. 1)从这张截图可以看出我会站在员工的角度讲述:(单向关联) 关系:(多个员工对应一个部门)多对一的关系 意味:多个Emp对象只会引用一个Dept对象 方法:在Emp类中定义一个Dept类型属性,来引用所有关联的Dept对象 eg. 第一步建立两个实体类省略 第二步建立大配置 <?xml version='1.0'

hibernate关联映射

本文可作为北京尚学堂马士兵hibernate课程的学习笔记. hibernate的映射,主要分为一对一,一对多,多对一,多对多,同时还要单向与双向的区别. OK,不要纠结于名字,我们开始看例子. 一对一单向 老公是一个实体,老婆也是一个实体. 一个老公只有一个老婆,同时一个老婆也只有一个老公. 上面的关系就叫做一对一. 什么叫单向呢. 看代码: package com.bjsxt.hibernate; @Entity public class Husband { private int id;

Hibernate关联映射 映射文件的配置

一:多对一单向关联 首先我们必须创建两个实体类 例如:Dept类 public class Dept { private Integer deptNo; private String dName; private String loc; private Set<Employee> emps=new HashSet<Employee>(); Employee类 public class Employee { private Integer empno; private String

Hibernate关联映射及高级查询

一.Hibernate中的关联关系 1.1.单向一对多关联关系 按照以下步骤配置hibernate中持久化类的一对多对象关联: (1).持久化类添加关联类的相关属性及getter/setter方法. (2).映射文件中建立该属性和数据库表字段的映射信息. 比如班级对学生是一对多的关系,班级类Grade类和Grade.hbm.xml文件如下: package com.pb.hibernate.po; import java.util.HashSet; import java.util.Set; p

Hibernate关联映射关系

一.双向一对多关联映射关系:当类与类之间建立了关联,就可以方便的从一个对象导航到另一个或另一组与它关联的对象(一对多双向关联和多对一双向关联是完全一样的) 1.1创建实体类(Emp(员工),Dept(部门)) /* * 员工实体类 */public class Emp { private Integer empId; //员工编号 private String empName; //员工姓名 private Dept dept; //所处部门 //get(),set()方法省略 } /* * 部

Hibernate 关联映射

ORM(Object Relational Mapping)对象/关系映射 说到Hibernate的关联映射就必须要提一提ORM了.那么ORM是什么呢,其是一种持久化技术,他在对象模型和关系型数据库之间建立对象关系,通过操作JavaBean对象来完成对数据库的操作! 注意:ORM是概念化的并不是实际存在的,可以理解为其是一种编程思想,而Hibernate框架就是该思想的实现产品! 配置Po对象(和数据表绑定的持久化对象)的关联关系 从上面说到ORM可以在对象模型和数据库之间建立对应关系而在Hib

hibernate关联映射之一对多&amp;多对一

package loaderman.b_one2Many; import java.util.HashSet; import java.util.Set; public class Dept { private int deptId; private String deptName; // [一对多] 部门对应的多个员工 private Set<Employee> emps = new HashSet<Employee>(); public int getDeptId() { re

hibernate关联映射【一对一主键】

从三个部分介绍Hibernate一对一主键关联映射. 1.基本介绍2.代码展示3.总结注意  1.基本介绍 一对一关联有两种情况: 单向一对一主键关联.双向一对一主键关联.一对一主键关联: 是指两个表之间通过主键形成一对一的映射,例如,每个公民只允许拥有一个身份证,公民与身份证就是一对一的关系,定义两张表,一张People表,一张IdCard表,People表的id既是该表的主键也是该表的外键,并且People的id也就是IdCard的id, 2.代码 单向一对一主键关联:people表的id既