转自CSDN 三毛村滴雪鱼粉的博客 url:https://blog.csdn.net/xfx_1994

实体关系是指实体与实体之间的关系,从方向上分为单向关联和双向关联,从实体数量上分为一对一、一对多、多对多等。对于任何两个实体,都要从这两个方面区分它们之间的关系。

一对多

表结构设计

banner表(一方)

  1. -- ----------------------------
  2. -- Table structure for banner
  3. -- ----------------------------
  4. DROP TABLE IF EXISTS `banner`;
  5. CREATE TABLE `banner` (
  6. `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  7. `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  8. `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
  9. `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
  10. `img` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '部分banner可能有标题图片',
  11. PRIMARY KEY (`id`)
  12. ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

banner_item表(多方)

  1. -- ----------------------------
  2. -- Table structure for banner_item
  3. -- ----------------------------
  4. DROP TABLE IF EXISTS `banner_item`;
  5. CREATE TABLE `banner_item` (
  6. `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  7. `img` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
  8. `keyword` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
  9. `type` smallint(5) unsigned NOT NULL DEFAULT '0',
  10. `banner_id` int(10) unsigned NOT NULL,
  11. `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
  12. PRIMARY KEY (`id`)
  13. ) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

单向一对多

一方Banner实体类

  1. @Entity
  2. @Getter
  3. @Setter
  4. public class Banner {
  5. @Id
  6. @GeneratedValue(strategy = GenerationType.IDENTITY)
  7. private Long id;
  8. private String name;
  9. private String description;
  10. private String title;
  11. private String img;
  12. @OneToMany(fetch = FetchType.LAZY) //fetch = FetchType.LAZY设置为懒加载
  13. @JoinColumn(name="bannerId") //指定外键名称
  14. private List<BannerItem> items;
  15. }

多方BannerItem实体类

  1. @Entity
  2. @Getter
  3. @Setter
  4. public class BannerItem {
  5. @Id
  6. @GeneratedValue(strategy = GenerationType.IDENTITY)
  7. private Long id;
  8. private String img;
  9. private String keyword;
  10. private short type;
  11. private String name;
  12. private Long bannerId;
  13. }

双向一对多

  1. @Entity
  2. @Table(name = "banner")
  3. public class Banner {
  4. @Id
  5. @GeneratedValue(strategy = GenerationType.IDENTITY)
  6. private long id;
  7. private String name;
  8. private String description;
  9. private String img;
  10. private String title;
  11. @OneToMany(mappedBy = "banner",fetch = FetchType.EAGER)
  12. private List<BannerItem> items;
  13. }
  1. @Entity
  2. public class BannerItem {
  3. @Id
  4. @GeneratedValue(strategy = GenerationType.IDENTITY)
  5. private Long id;
  6. private String img;
  7. private String keyword;
  8. private Short type;
  9. private String name;
  10. @ManyToOne
  11. @JoinColumn(name="bannerId")
  12. private Banner banner;
  13. }

总结
双向一对多关系中
1.在一方打上@OneToMany,在多方打上@ManyToOne
2.需要指明关联的外键@JoinColumn打在多方也就是关系维护方上
3.在关系的被维护方也就是一方的@OneToMany增加一个参数mappedBy,值是多方中的导航属性的名字

双向一对多的外键配置问题

我们原来在banner中手动添加的banner就没有实际的业务意义了,banner只是表明两个表的关系。在双向关系中bannerId是会自动生成的。这里不能显示的声明bannerId,自动创建表的时候会自动生成banner_id。如果一定想让bannerId显示的表达出来要么就使用单向一对多,或者使用双向一对多但是要在@JoinColumn中添加两个参数

  1. @ManyToOne
  2. @JoinColumn(insertable = false,updatable = false,name="bannerId")
  3. private Banner banner;

多对多

表结构设计

  1. -- ----------------------------
  2. -- Table structure for theme
  3. -- ----------------------------
  4. DROP TABLE IF EXISTS `theme`;
  5. CREATE TABLE `theme` (
  6. `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  7. `title` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
  8. `name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
  9. PRIMARY KEY (`id`)
  10. ) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
  1. -- ----------------------------
  2. -- Table structure for spu
  3. -- ----------------------------
  4. DROP TABLE IF EXISTS `spu`;
  5. CREATE TABLE `spu` (
  6. `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  7. `title` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  8. `subtitle` varchar(800) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
  9. PRIMARY KEY (`id`)
  10. ) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
  1. -- ----------------------------
  2. -- Table structure for theme_spu
  3. -- ----------------------------
  4. DROP TABLE IF EXISTS `theme_spu`;
  5. CREATE TABLE `theme_spu` (
  6. `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  7. `theme_id` int(10) unsigned NOT NULL,
  8. `spu_id` int(10) unsigned NOT NULL,
  9. PRIMARY KEY (`id`)
  10. ) ENGINE=InnoDB AUTO_INCREMENT=101 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

单向多对多

在有些业务中我们是不需要双向多对多的。
默认规则为我们生成的第三张表的命名存在一些问题,我们需要去指定第三张表的名称和第三张表中外键的名称。
使用@JoinTable,参数name指定第三表的表名;joinColumns 和inverseJoinColumns 用于定义外键的名称。

  1. package com.lin.missyou.model;
  2. import javax.persistence.*;
  3. import java.util.List;
  4. @Entity
  5. public class Theme {
  6. @Id
  7. private Long id;
  8. private String title;
  9. private String name;
  10. @ManyToMany
  11. @JoinTable(name="theme_spu",
  12. joinColumns = @JoinColumn(name="theme_id"),
  13. inverseJoinColumns = @JoinColumn(name="spu_id"))
  14. private List<Spu> spuList;
  15. }
  1. @Entity
  2. public class Spu {
  3. @Id
  4. private Long id;
  5. private String title;
  6. private String subtitle;
  7. }

双向多对多

用@ManyToMany(mappedBy = “spuList”)声明关系的被维护端。此处双向多对多与双向一对多就有所区别,双向多对多维护端与被维护端是可以调换的,而双向一对多的维护端与被维护端是不可以调换的。

  1. @Entity
  2. public class Theme {
  3. @Id
  4. private Long id;
  5. private String title;
  6. private String name;
  7. @ManyToMany
  8. @JoinTable(name="theme_spu",
  9. joinColumns = @JoinColumn(name="theme_id"),
  10. inverseJoinColumns = @JoinColumn(name="spu_id"))
  11. private List<Spu> spuList;
  12. }
  1. @Entity
  2. public class Spu {
  3. @Id
  4. private Long id;
  5. private String title;
  6. private String subtitle;
  7. @ManyToMany(mappedBy = "spuList")
  8. private List<Theme> themeList;
  9. }