转自CSDN 三毛村滴雪鱼粉的博客 url:https://blog.csdn.net/xfx_1994
实体关系是指实体与实体之间的关系,从方向上分为单向关联和双向关联,从实体数量上分为一对一、一对多、多对多等。对于任何两个实体,都要从这两个方面区分它们之间的关系。
一对多
表结构设计
banner表(一方)
-- ------------------------------ Table structure for banner-- ----------------------------DROP TABLE IF EXISTS `banner`;CREATE TABLE `banner` (`id` int(11) unsigned NOT NULL AUTO_INCREMENT,`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,`description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,`title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,`img` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '部分banner可能有标题图片',PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
banner_item表(多方)
-- ------------------------------ Table structure for banner_item-- ----------------------------DROP TABLE IF EXISTS `banner_item`;CREATE TABLE `banner_item` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT,`img` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,`keyword` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,`type` smallint(5) unsigned NOT NULL DEFAULT '0',`banner_id` int(10) unsigned NOT NULL,`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
单向一对多
一方Banner实体类
@Entity@Getter@Setterpublic class Banner {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String name;private String description;private String title;private String img;@OneToMany(fetch = FetchType.LAZY) //fetch = FetchType.LAZY设置为懒加载@JoinColumn(name="bannerId") //指定外键名称private List<BannerItem> items;}
多方BannerItem实体类
@Entity@Getter@Setterpublic class BannerItem {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String img;private String keyword;private short type;private String name;private Long bannerId;}
双向一对多
@Entity@Table(name = "banner")public class Banner {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private long id;private String name;private String description;private String img;private String title;@OneToMany(mappedBy = "banner",fetch = FetchType.EAGER)private List<BannerItem> items;}
@Entitypublic class BannerItem {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String img;private String keyword;private Short type;private String name;@ManyToOne@JoinColumn(name="bannerId")private Banner banner;}
总结
双向一对多关系中
1.在一方打上@OneToMany,在多方打上@ManyToOne
2.需要指明关联的外键@JoinColumn打在多方也就是关系维护方上
3.在关系的被维护方也就是一方的@OneToMany增加一个参数mappedBy,值是多方中的导航属性的名字
双向一对多的外键配置问题
我们原来在banner中手动添加的banner就没有实际的业务意义了,banner只是表明两个表的关系。在双向关系中bannerId是会自动生成的。这里不能显示的声明bannerId,自动创建表的时候会自动生成banner_id。如果一定想让bannerId显示的表达出来要么就使用单向一对多,或者使用双向一对多但是要在@JoinColumn中添加两个参数
@ManyToOne@JoinColumn(insertable = false,updatable = false,name="bannerId")private Banner banner;
多对多
表结构设计
-- ------------------------------ Table structure for theme-- ----------------------------DROP TABLE IF EXISTS `theme`;CREATE TABLE `theme` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT,`title` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,`name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- ------------------------------ Table structure for spu-- ----------------------------DROP TABLE IF EXISTS `spu`;CREATE TABLE `spu` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT,`title` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,`subtitle` varchar(800) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- ------------------------------ Table structure for theme_spu-- ----------------------------DROP TABLE IF EXISTS `theme_spu`;CREATE TABLE `theme_spu` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT,`theme_id` int(10) unsigned NOT NULL,`spu_id` int(10) unsigned NOT NULL,PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=101 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
单向多对多
在有些业务中我们是不需要双向多对多的。
默认规则为我们生成的第三张表的命名存在一些问题,我们需要去指定第三张表的名称和第三张表中外键的名称。
使用@JoinTable,参数name指定第三表的表名;joinColumns 和inverseJoinColumns 用于定义外键的名称。
package com.lin.missyou.model;import javax.persistence.*;import java.util.List;@Entitypublic class Theme {@Idprivate Long id;private String title;private String name;@ManyToMany@JoinTable(name="theme_spu",joinColumns = @JoinColumn(name="theme_id"),inverseJoinColumns = @JoinColumn(name="spu_id"))private List<Spu> spuList;}
@Entitypublic class Spu {@Idprivate Long id;private String title;private String subtitle;}
双向多对多
用@ManyToMany(mappedBy = “spuList”)声明关系的被维护端。此处双向多对多与双向一对多就有所区别,双向多对多维护端与被维护端是可以调换的,而双向一对多的维护端与被维护端是不可以调换的。
@Entitypublic class Theme {@Idprivate Long id;private String title;private String name;@ManyToMany@JoinTable(name="theme_spu",joinColumns = @JoinColumn(name="theme_id"),inverseJoinColumns = @JoinColumn(name="spu_id"))private List<Spu> spuList;}
@Entitypublic class Spu {@Idprivate Long id;private String title;private String subtitle;@ManyToMany(mappedBy = "spuList")private List<Theme> themeList;}
