资讯专栏INFORMATION COLUMN

JPA关系映射

Faremax / 1827人阅读

摘要:关系映射四种映射关系在关系数据库中有表与表存在下面几种关系多对一关系一对一关系一对多关系多对多关系也对应这中四种映射关系单值串联从一个实体实例关联到另一个实体实例上其中目标基数为成为单值关联多对一关系和一对一关系都是属于这

JPA关系映射 四种映射关系

在关系数据库中, 有表与表存在下面几种关系

多对一关系(Many-to-One)

一对一关系(One-to-One)

一对多关系(One-to-Many)

多对多关系(Many-to-Many)

也对应这JPA中四种映射关系.

单值串联

从一个实体实例关联到另一个实体实例上, 其中目标基数为1, 成为单值关联(single-valued association).
多对一关系和一对一关系都是属于这一类, 因为源实体至多引用了一个目标实体.

多对一关联(ManyToOne)

来看这么一个关系, 员工(employee)和部门(department)之间的关系, 显然一个员工只能属于一个部门, 而一个部门
内当然拥有多个员工, 所以从员工到部门的映射关系是多对一关系.

employee实体类

@Entity
public class Employee {
    @Id
    private Integer id;
    private String name;
    private Long salary;

    @ManyToOne
    private Department department;

    public Employee() {
    }

    public Employee(Integer id) {
        this.id = id;
    }
}

department实体类

@Data
@Entity
public class Department {
    @Id
    private Integer id;

    private String name;

}

程序运行后, jpa创建表的sql语句如下

+------------+--------------------------------------+
| Table      | Create Table                         |
+------------+--------------------------------------+
| department | CREATE TABLE `department` (          |
|            |   `id` int(11) NOT NULL,             |
|            |   `name` varchar(255) DEFAULT NULL,  |
|            |   PRIMARY KEY (`id`)                 |
|            | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+------------+--------------------------------------+

+----------+---------------------------------------------------------------------------------------------------------+
| Table    | Create Table                                                                                            |
+----------+---------------------------------------------------------------------------------------------------------+
| employee | CREATE TABLE `employee` (                                                                               |
|          |   `id` int(11) NOT NULL,                                                                                |
|          |   `name` varchar(255) DEFAULT NULL,                                                                     |
|          |   `salary` bigint(20) DEFAULT NULL,                                                                     |
|          |   `department_id` int(11) DEFAULT NULL,                                                                 |
|          |   PRIMARY KEY (`id`),                                                                                   |
|          |   KEY `FKbejtwvg9bxus2mffsm3swj3u9` (`department_id`),                                                  |
|          |   CONSTRAINT `FKbejtwvg9bxus2mffsm3swj3u9` FOREIGN KEY (`department_id`) REFERENCES `department` (`id`) |
|          | ) ENGINE=InnoDB DEFAULT CHARSET=utf8                                                                    |
+----------+---------------------------------------------------------------------------------------------------------+

department_id是jpa创建的外键, 如果想指定外键的名字, 可以通过@JoinColumn来声明外键的名字

一对一映射

对于员工来说, 只有一个停车位(PackingSpace), 所以员工对停车位来说是一对一映射关系
修改EMPLOYEE类

@Data
@Entity
public class Employee {
    @Id
    private Integer id;
    private String name;
    private Long salary;

    @ManyToOne
    @JoinColumn(name = "dept_id")
    private Department department;

    @OneToOne
    @JoinColumn(name = "p_space_id")
    private ParkingSpace parkingSpace;

    public Employee() {
    }

    public Employee(Integer id) {
        this.id = id;
    }
}

创建PackingSpace实体类

@Data
@Entity
public class ParkingSpace {
    @Id
    private Integer id;

    private String location;
}

查看parking_space表和employee表

+---------------+-----------------------------------------+
| Table         | Create Table                            |
+---------------+-----------------------------------------+
| parking_space | CREATE TABLE `parking_space` (          |
|               |   `id` int(11) NOT NULL,                |
|               |   `location` varchar(255) DEFAULT NULL, |
|               |   PRIMARY KEY (`id`)                    |
|               | ) ENGINE=InnoDB DEFAULT CHARSET=utf8    |
+---------------+-----------------------------------------+
+----------+---------------------------------------------------------------------------------------------------------+
| Table    | Create Table                                                                                            |
+----------+---------------------------------------------------------------------------------------------------------+
| employee | CREATE TABLE `employee` (                                                                               |
|          |   `id` int(11) NOT NULL,                                                                                |
|          |   `name` varchar(255) DEFAULT NULL,                                                                     |
|          |   `salary` bigint(20) DEFAULT NULL,                                                                     |
|          |   `dept_id` int(11) DEFAULT NULL,                                                                       |
|          |   `p_space_id` int(11) DEFAULT NULL,                                                                    |
|          |   PRIMARY KEY (`id`),                                                                                   |
|          |   KEY `FKaqchbcb8i6nvtl9g6c72yba0p` (`dept_id`),                                                        |
|          |   KEY `FKd383146ko181lfhm1xuy3arci` (`p_space_id`),                                                     |
|          |   CONSTRAINT `FKaqchbcb8i6nvtl9g6c72yba0p` FOREIGN KEY (`dept_id`) REFERENCES `department` (`id`),      |
|          |   CONSTRAINT `FKd383146ko181lfhm1xuy3arci` FOREIGN KEY (`p_space_id`) REFERENCES `parking_space` (`id`) |
|          | ) ENGINE=InnoDB DEFAULT CHARSET=utf8                                                                    |
+----------+---------------------------------------------------------------------------------------------------------+
双向一对一映射

对于员工来说, 至多只能拥有一个停车位, 对于停车位来说, 也至多只能属于一个员工, 所以两个方向都是一对一关系, 这被称为双向一对一关系

修改ParkingSpace实体类

@Data
@Entity
public class ParkingSpace {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    private String location;

    @OneToOne(mappedBy = "parkingSpace")
    @JoinColumn(name = "emp_id")
    private Employee employee;

    @Override
    public String toString() {
        return "ParkingSpace{" +
                "id=" + id +
                ", location="" + location + """ +
                "}";
    }
}

在双向一对一关系中, 如果双方都有mapperBy, name这样是不合法, 如果双方都没有mapperBy, 这样是不正确的, 因为如果双方都没有mapperBy,
则当前不是双向一对一关系, 而是两个单向的一对一关系.

集合值关联

当源实体引用一个或者多个目标实体实例时, 将使用一个多值关联(many-valued association). 一对多关联和多对多映射都符合

一对多映射

前面对于员工来说, 对于部门是多对一映射, 多个员工属于一个部门, 相反的, 对于部门来说, 对员工是一对多的映射, 对于一个部门来说, 拥有多个员工,
所以也是双向的关系

修改department实体类

@Data
@Entity
public class Department {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    private String name;

   @OneToMany(mappedBy = "department")
    private List employees;
}
多对多映射

员工与项目的关系也是多对多的关系, 一个员工大概率不会只会做一个项目, 一个项目大概率也不会只交给一个员工做

增加项目实体类

@Data
@Entity
public class Project {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    private String name;

    @ManyToMany(mappedBy = "projects")
    private List employees;
}

在员工实体类中添加如下

    @ManyToMany
    private List projects;

查看创建的表

+---------------------+
| Tables_in_db_projpa |
+---------------------+
| department          |
| employee            |
| employee_projects   |
| hibernate_sequence  |
| parking_space       |
| project             |
+---------------------+

可以看到除了创建project表外, 还创建了表employee_projects表, 没有对这个连接表进行配置, 是根据jpa默认规则进行创建的, 创表的sql语句为

+-------------------+-------------------------------------------------------------------------------------------------------+
| Table             | Create Table                                                                                          |
+-------------------+-------------------------------------------------------------------------------------------------------+
| employee_projects | CREATE TABLE `employee_projects` (                                                                    |
|                   |   `employees_id` int(11) NOT NULL,                                                                    |
|                   |   `projects_id` int(11) NOT NULL,                                                                     |
|                   |   KEY `FKg10a7uho2lylw8g080l5j4gyk` (`projects_id`),                                                  |
|                   |   KEY `FK88mdj5vmp7md19u4cbq154dk6` (`employees_id`),                                                 |
|                   |   CONSTRAINT `FK88mdj5vmp7md19u4cbq154dk6` FOREIGN KEY (`employees_id`) REFERENCES `employee` (`id`), |
|                   |   CONSTRAINT `FKg10a7uho2lylw8g080l5j4gyk` FOREIGN KEY (`projects_id`) REFERENCES `project` (`id`)    |
|                   | ) ENGINE=InnoDB DEFAULT CHARSET=utf8                                                                  |
+-------------------+-------------------------------------------------------------------------------------------------------+
使用@JoinTable来配置连接表

修改员工实体类, 添加@JoinTable注解

    @ManyToMany
    @JoinTable(name = "emp_proj", joinColumns = @JoinColumn(name = "emp_id"), inverseJoinColumns = @JoinColumn(name = "proj_id"))
    private List projects;

可以看到表名和字段名都相应变化了

+----------+-------------------------------------------------------------------------------------------------+
| Table    | Create Table                                                                                    |
+----------+-------------------------------------------------------------------------------------------------+
| emp_proj | CREATE TABLE `emp_proj` (                                                                       |
|          |   `emp_id` int(11) NOT NULL,                                                                    |
|          |   `proj_id` int(11) NOT NULL,                                                                   |
|          |   KEY `FKj350n5wr8yyesit27cw0agpjq` (`proj_id`),                                                |
|          |   KEY `FK10tf71i5h7os8kdrpm2k97gn2` (`emp_id`),                                                 |
|          |   CONSTRAINT `FK10tf71i5h7os8kdrpm2k97gn2` FOREIGN KEY (`emp_id`) REFERENCES `employee` (`id`), |
|          |   CONSTRAINT `FKj350n5wr8yyesit27cw0agpjq` FOREIGN KEY (`proj_id`) REFERENCES `project` (`id`)  |
|          | ) ENGINE=InnoDB DEFAULT CHARSET=utf8                                                            |
+----------+-------------------------------------------------------------------------------------------------+
参考资料

Pro JPA 2: 精通Java持久化API

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/76633.html

相关文章

  • Spring Data JPA关系映射@OneToOne

    摘要:表示一对一的映射关系,比如一个账号对应一个用户,一个实体用来描述账号的信息账号,密码,账号是否可用,账号对应的角色等,另外一个实体用来描述用户的信息昵称,年龄,性别,国籍等。这里贴出源码,一个关系映射的小例子原创不易,感谢支持。 @OneToOne, 表示一对一的映射关系,比如一个账号对应一个用户,一个实体用来描述账号的信息(账号,密码,账号是否可用,账号对应的角色等),另外一个实体用...

    zhangke3016 评论0 收藏0
  • 如何借助 NoSQL 提高 JPA 应用性能

    摘要:当时,还饱受微软和太阳间的诉讼的影响,该诉讼涉及到和间的兼容性。开发者们都在讨论哪个平台或者框架能够胜出还是微软新发布的。能为您提供端到端的应用性能解决方案,我们支持所有常见的框架及应用服务器,助您快速发现系统瓶颈,定位异常根本原因。 【编者按】关注 NoSQL 的动态发展很重要。NoSQL 的好处并不仅限于新的应用开发。在某些案例中,你可以见识到重新访问现有的、传统的框架带来的积极效...

    Airy 评论0 收藏0
  • String Data JPA 学习笔记

    摘要:说明首先来说是一个持久化规范,也就是说当我们用的时候我们不需要去选面向的编程了,这样就大大降低了偶和度了引入是一种规范,那么它的编程有哪些要求呢引入下载的包导入文件夹,然后我们的在下面加上一个目录在该文件夹下面加上一个文件,这个文件的规范 说明 首先来说JPA是一个持久化规范,也就是说当我们用jpa的时候我们不需要去选面向hibernate的api编程了,这样就大大降低了偶和度了 引入...

    Java_oldboy 评论0 收藏0

发表评论

0条评论

Faremax

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<