JPA映射关系配置(一对多、多对多)

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

一对多

表结构设计

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
@Setter
public 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
@Setter
public 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;
}
@Entity
public 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;

@Entity
public class Theme {
    @Id
    private 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;
}
@Entity
public class Spu {
    @Id
    private Long id;
    private String title;
    private String subtitle;
}

双向多对多

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

@Entity
public class Theme {
    @Id
    private 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;
}
@Entity
public class Spu {
    @Id
    private Long id;
    private String title;
    private String subtitle;

    @ManyToMany(mappedBy = "spuList")
    private List<Theme> themeList;
}

猜你喜欢

转载自blog.csdn.net/xfx_1994/article/details/104699976