在关系数据库中, 有表与表存在下面几种关系java
也对应这JPA中四种映射关系.sql
从一个实体实例关联到另外一个实体实例上, 其中目标基数为1, 成为单值关联(single-valued association).
多对一关系和一对一关系都是属于这一类, 由于源实体至多引用了一个目标实体.数据库
来看这么一个关系, 员工(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注解
@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