JPA關係映射

JPA關係映射

四種映射關係

在關係數據庫中, 有表與表存在下面幾種關係java

  • 多對一關係(Many-to-One)
  • 一對一關係(One-to-One)
  • 一對多關係(One-to-Many)
  • 多對多關係(Many-to-Many)

也對應這JPA中四種映射關係.sql

單值串聯

從一個實體實例關聯到另外一個實體實例上, 其中目標基數爲1, 成爲單值關聯(single-valued association).
多對一關係和一對一關係都是屬於這一類, 由於源實體至多引用了一個目標實體.數據庫

多對一關聯(ManyToOne)

來看這麼一個關係, 員工(employee)和部門(department)之間的關係, 顯然一個員工只能屬於一個部門, 而一個部門
內固然擁有多個員工, 因此從員工到部門的映射關係是多對一關係.app

employee實體類ide

@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實體類this

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

    private String name;

}

程序運行後, jpa建立表的sql語句以下spa

+------------+--------------------------------------+
| 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來聲明外鍵的名字hibernate

一對一映射

對於員工來講, 只有一個停車位(PackingSpace), 因此員工對停車位來講是一對一映射關係
修改EMPLOYEE類code

@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實體類ci

@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<Employee> employees;
}

多對多映射

員工與項目的關係也是多對多的關係, 一個員工大機率不會只會作一個項目, 一個項目大機率也不會只交給一個員工作

增長項目實體類

@Data
@Entity
public class Project {

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

    private String name;

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

在員工實體類中添加以下

@ManyToMany
    private List<Project> 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<Project> 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

相關文章
相關標籤/搜索