博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hibernate关联映射
阅读量:6148 次
发布时间:2019-06-21

本文共 10020 字,大约阅读时间需要 33 分钟。

本文可作为北京尚学堂马士兵hibernate课程的学习笔记。

hibernate的映射,主要分为一对一,一对多,多对一,多对多,同一时候还要单向与双向的差别。

OK,不要纠结于名字,我们開始看样例。

一对一单向

老公是一个实体,老婆也是一个实体。
一个老公仅仅有一个老婆,同一时候一个老婆也仅仅有一个老公。
上面的关系就叫做一对一。

什么叫单向呢。
看代码:

package com.bjsxt.hibernate;@Entitypublic class Husband {    private int id;    private String name;    private Wife wife;        @Id    @GeneratedValue    public int getId() {        return id;    }        @OneToOne    @JoinColumn(name="wifeId")    public Wife getWife() {        return wife;    }    //省略get set}package com.bjsxt.hibernate;@Entitypublic class Wife {    private int id;    private String name;        @Id    @GeneratedValue    public int getId() {        return id;    }    //省略get set}
看上面的代码,老公里面有老婆的引用,而老婆里面并没有老婆的引用。
换句话说在代码层次上,依据老公我们能够获得他的老婆,可是依据老婆无法获得老公。(这就是单向)
我们看看它执行的代码
package com.bjsxt.hibernate;import org.hibernate.cfg.AnnotationConfiguration;import org.hibernate.tool.hbm2ddl.SchemaExport;public class Test {    public static void main(String[] args) {        new SchemaExport(new AnnotationConfiguration().configure()).create(false, true);        }}
在hibernate的配置文件中
加上
update
结果
19:41:04,229 DEBUG org.hibernate.tool.hbm2ddl.SchemaExport:377 -    create table Husband (        id integer not null auto_increment,        name varchar(255),        wifeId integer,        primary key (id)    )19:41:04,549 DEBUG org.hibernate.tool.hbm2ddl.SchemaExport:377 -    create table Wife (        id integer not null auto_increment,        name varchar(255),        primary key (id)    )19:41:04,880 DEBUG org.hibernate.tool.hbm2ddl.SchemaExport:377 -    alter table Husband        add index FKAEEA401B109E78ED (wifeId),        add constraint FKAEEA401B109E78ED        foreign key (wifeId)        references Wife (id)
先给husband加了一个字段,wifeId,然后让他作为外键引用wife表的id字段。
大家能够看到,@JoinColumn(name="wifeId")这个元标签指示了husband表内部那那个关联字段的名字。
假设没有这个元标签呢?
那么关联字段就是是:wife_id。

即tableName_primarykey。

假设把 @onetoone写到Wife里(husband里没有onotoone的标签),那么我们就能从wife获得husband了(在代码层次)。

一对一双向

假设我既想从husband里取得wife,也想从wife里取得husband。那咋办?

把husband里的标签复制一遍就OK了嘛。

package com.bjsxt.hibernate;@Entitypublic class Wife {    private int id;    private String name;    private Husband husband;        @Id    @GeneratedValue    public int getId() {        return id;    }        @OneToOne    @JoinColumn(name="husbandId")    public Husband getHusband() {        return husband;    }}
OK,上面的代码里,wife也能够取到husband了。
我们看看hibernate生成的sql
create table Husband (        id integer not null auto_increment,        name varchar(255),        wifeId integer,        primary key (id)    )19:53:20,487 DEBUG org.hibernate.tool.hbm2ddl.SchemaExport:377 -    create table Wife (        id integer not null auto_increment,        name varchar(255),        husbandId integer,        primary key (id)    )19:53:20,824 DEBUG org.hibernate.tool.hbm2ddl.SchemaExport:377 -    alter table Husband        add index FKAEEA401B109E78ED (wifeId),        add constraint FKAEEA401B109E78ED        foreign key (wifeId)        references Wife (id)19:53:21,421 DEBUG org.hibernate.tool.hbm2ddl.SchemaExport:377 -    alter table Wife        add index FK292331CE01A6E1 (husbandId),        add constraint FK292331CE01A6E1        foreign key (husbandId)        references Husband (id)
看见了吧,wife里面有外键,husband里面也有外键!
这不是冗余了嘛。
把wife类改成以下的样子
@OneToOne(mappedBy="wife")    public Husband getHusband() {        return husband;    }
这个mappedBy的意思是说,我(Wife这个类)和husband这个类是一对一关联的,可是关联的外键由husband类的getWife方法控制。
执行一下。
20:03:18,611 DEBUG org.hibernate.tool.hbm2ddl.SchemaExport:377 -    create table Husband (        id integer not null auto_increment,        name varchar(255),        wifeId integer,        primary key (id)    )20:03:18,618 ERROR org.hibernate.tool.hbm2ddl.SchemaExport:348 - Unsuccessful: create table Husband (id integer not null auto_increment, name varchar(255), wifeId integer, primary key (id))20:03:18,618 ERROR org.hibernate.tool.hbm2ddl.SchemaExport:349 - Table 'husband' already exists20:03:18,619 DEBUG org.hibernate.tool.hbm2ddl.SchemaExport:377 -    create table Wife (        id integer not null auto_increment,        name varchar(255),        primary key (id)    )20:03:18,933 DEBUG org.hibernate.tool.hbm2ddl.SchemaExport:377 -    alter table Husband        add index FKAEEA401B109E78ED (wifeId),        add constraint FKAEEA401B109E78ED        foreign key (wifeId)        references Wife (id)
数据库里,wife表里没有外键了。
可是,在代码层次我们依旧能够从Wife类里获得Husband。

注意上面的 @OneToOne(mappedBy="wife")
仅仅有是双向关联,最好就都写上mappedBy,两张表有一个外键就够了。

多对一单向关联

每个人都会有非常多个梦想,可是每个梦想仅仅属于某一个详细的人。
我们先无论java代码上怎样实现,在数据库里。
上面的两张表,一个是person,里面就是id,name
再就是dream表,一个id,一个description。
那么它们的外键放在哪张表里呢?

放在dream里,换言之,dream表里有一个字段叫personId。

这个的原因,不用解释。

全部一对多,多对一的关系,在数据库里,外键都是放在多的一方里的。
为什么。自己想。

看代码

package com.bjsxt.hibernate;@Entitypublic class Dream {    private int id;    private String description;        private Person person;        @Id    @GeneratedValue    public int getId() {        return id;    }    @ManyToOne    @JoinColumn(name="personId")    public Person getPerson() {        return person;    }    //省略get set}package com.bjsxt.hibernate;@Entitypublic class Person {    private int id;    private String name;        @Id    @GeneratedValue    public int getId() {        return id;    }        //省略get set}
从代码层次上看"多对一单向"
就是我能够从多的一方(dream)里获得一的那一方(person)。

由于是单向,所以不能从person获得他全部的dream。
OK,生成的表里,dream里有personid。

20:20:21,970 DEBUG org.hibernate.tool.hbm2ddl.SchemaExport:377 -    create table Dream (        id integer not null auto_increment,        description varchar(255),        personId integer,        primary key (id)    )20:20:22,264 DEBUG org.hibernate.tool.hbm2ddl.SchemaExport:377 -    create table Person (        id integer not null auto_increment,        name varchar(255),        primary key (id)    )20:20:22,765 DEBUG org.hibernate.tool.hbm2ddl.SchemaExport:377 -    alter table Dream        add index FK3F397E3C1409475 (personId),        add constraint FK3F397E3C1409475        foreign key (personId)        references Person (id)

一对多单向关联

还是人与梦想的样例。
我想在代码层次,通过人获得他的全部的梦想,怎么办?
首先在dream类里删除person的引用
package com.bjsxt.hibernate;@Entitypublic class Person {    private int id;    private String name;    private Set
dreams=new HashSet<>(); @Id @GeneratedValue public int getId() { return id; } @OneToMany @JoinColumn(name="psrsonId") public Set
getDreams() { return dreams; } }
OK,大功告成。

建表语句和上面的一样。
装dream的集合类为什么是set?

list行不,map行不?

都行。
可是记着,数据库里面的记录是无序且不相等的。
你说用哪个?

无论是oneToMany还是manyToMany,加的 @JoinColumn(name="abc")
都是在多的一方增加指向少的一方的名叫abc的外键。

一对多双向关联(多对一双向关联)

以下的样例,大家猜也猜到了,我既想从dream获得它所属的person,还想从person获得他全部的dream。
我们看代码:
package com.bjsxt.hibernate;@Entitypublic class Dream {    private int id;    private String description;        private Person person;        @Id    @GeneratedValue    public int getId() {        return id;    }    public void setId(int id) {        this.id = id;    }    @ManyToOne    @JoinColumn(name="personId")    public Person getPerson() {        return person;    }}package com.bjsxt.hibernate;@Entitypublic class Person {    private int id;    private String name;    private Set
dreams=new HashSet<>(); @Id @GeneratedValue public int getId() { return id; } @OneToMany(mappedBy="person") public Set
getDreams() { return dreams; }}
ok,我们能够在代码里,通过dream获得person也能够通过person获得dream

多对多单向关联

样例非常easy,一个老师能够教多个学生,一个学生能够被多个老师教。
单向是说,要么老师能"知道"自己的学生,要么学生能知道自己的老师。
我们先看老师能"知道"自己学生的代码。
package com.bjsxt.hibernate;@Entitypublic class Student {    private int id;    private String name;        @Id    @GeneratedValue    public int getId() {        return id;    }}OK,学生里面没有老师的引用。package com.bjsxt.hibernate;@Entitypublic class Teacher {    private int id;    private String name;    private Set
students = new HashSet
(); @Id @GeneratedValue public int getId() { return id; } @ManyToMany @JoinTable(name="t_s", joinColumns={@JoinColumn(name="teacher_id")}, inverseJoinColumns={@JoinColumn(name="student_id")} ) public Set
getStudents() { return students; }}
看结果:
21:10:35,854 DEBUG org.hibernate.tool.hbm2ddl.SchemaExport:377 -    create table Student (        id integer not null auto_increment,        name varchar(255),        primary key (id)    )21:10:36,192 DEBUG org.hibernate.tool.hbm2ddl.SchemaExport:377 -    create table Teacher (        id integer not null auto_increment,        name varchar(255),        primary key (id)    )21:10:36,643 DEBUG org.hibernate.tool.hbm2ddl.SchemaExport:377 -    create table t_s (        teacher_id integer not null,        student_id integer not null,        primary key (teacher_id, student_id)    )21:10:36,947 DEBUG org.hibernate.tool.hbm2ddl.SchemaExport:377 -    alter table t_s        add index FK1BF68BF77BA8A (teacher_id),        add constraint FK1BF68BF77BA8A        foreign key (teacher_id)        references Teacher (id)21:10:37,588 DEBUG org.hibernate.tool.hbm2ddl.SchemaExport:377 -    alter table t_s        add index FK1BF68AEDC6FEA (student_id),        add constraint FK1BF68AEDC6FEA        foreign key (student_id)        references Student (id)21:10:38,263  INFO org.hibernate.tool.hbm2ddl.SchemaExport:268 - schema export complete
我们看看生成的t_s表和里面的字段名称应该就能明确 @JoinTable的作用
它就是在manytomany时,指定第三张表的表名和字段。

joinColumns 指的是指向自己这个类的字段名
inverseJoinColumns inverse是反向的意思 所以这个标签就是运行另外那个类的字段
假设没有 @JoinTable这个标签,会是什么样子呢?大家自己试一下。
另外,上面的代码是从老师到学生,大家再试试从学生到老师。

多对多双向关联

在上面的样例里

改变student,给它加上teacher的引用。

package com.bjsxt.hibernate;@Entitypublic class Student {    private int id;    private String name;    private Set
teachers=new HashSet<>(); @Id @GeneratedValue public int getId() { return id; } //记着 双向的时候 就加上mappedBy @ManyToMany(mappedBy="students") public Set
getTeachers() { return teachers; }}

glt likes dlf

dlf likes glt

oneToOne

转载地址:http://azwfa.baihongyu.com/

你可能感兴趣的文章
在mac OS10.10下安装 cocoapods遇到的一些问题
查看>>
angularjs表达式中的HTML内容,如何不转义,直接表现为html元素
查看>>
css技巧
查看>>
Tyvj 1728 普通平衡树
查看>>
javascript性能优化
查看>>
多路归并排序之败者树
查看>>
java连接MySql数据库
查看>>
转:Vue keep-alive实践总结
查看>>
深入python的set和dict
查看>>
C++ 11 lambda
查看>>
Android JSON数据解析
查看>>
DEV实现日期时间效果
查看>>
java注解【转】
查看>>
centos 下安装g++
查看>>
嵌入式,代码调试----GDB扫盲
查看>>
类斐波那契数列的奇妙性质
查看>>
下一步工作分配
查看>>
Response. AppendHeader使用大全及文件下载.net函数使用注意点(转载)
查看>>
Wait Functions
查看>>
jQuery最佳实践
查看>>