1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > Spring Data 数据库建模最佳实践

Spring Data 数据库建模最佳实践

时间:2021-01-02 04:41:24

相关推荐

Spring Data 数据库建模最佳实践

本文节选自电子书《Netkiller Architect 手札》

出处:

作者:netkiller , QQ:13721218, 订阅号:netkiller-ebook

第12章Spring Data 数据库建模最佳实践

目录

12.1. 分类表12.2. 为字段增加索引12.3. 复合索引12.4. 一对多实例12.5. ManyToMany 多对多12.6. 外键级联删除

ORM的出现解决了程序猿学习数据库学历成本,也加快了开发的速度。程序猿无需再学习数据库定义语言DDL以及数据库客户端,也无需关注建表这些繁琐的工作,同时也降低了数据库结构变更管理中与DBA频繁沟通的成本。

在过去的两年中我们采用 Spring Data JPA 定义数据库,访问数据库,积累了很多经验,最终我们发现使用 Spring Data 实体定义完全可以代替 DBA 的建模工作。

下面我们采用案例,一个一个讲解,各种数据库实体关系的定义。相关数据库建模知识请先阅读《Netkiller Architect 手札》以及《Netkiller Spring 手札》

12.1.分类表

这是一个通用分类表,常见的父子关系加上path路径

+-----------+| category ||-----------||id | <---+|name |||description| 1:n|status|||pid | o---+|path ||status||ctime||mtime|+-----------+

package common.domain;import java.util.Date;import java.util.Set;import javax.persistence.CascadeType;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.FetchType;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.ManyToOne;import javax.persistence.OneToMany;import org.springframework.format.annotation.DateTimeFormat;import com.fasterxml.jackson.annotation.JsonFormat;import com.fasterxml.jackson.annotation.JsonIgnore;@Entitypublic class Category {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "id", unique = true, nullable = false, insertable = true, updatable = false)public int id;public String name;public String description;public String path;@Column(columnDefinition = "enum('Enabled','Disabled') DEFAULT 'Enabled' COMMENT '状态'")public String status;@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")@Column(columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间'")public Date ctime;@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")@Column(columnDefinition = "TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更改时间'")public Date mtime;@ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })@JoinColumn(name = "pid", referencedColumnName = "id")private Category categorys;@JsonIgnore@OneToMany(cascade = CascadeType.ALL, mappedBy = "category", fetch = FetchType.EAGER)private Set<Category> category;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}public String getPath() {return path;}public void setPath(String path) {this.path = path;}public String getStatus() {return status;}public void setStatus(String status) {this.status = status;}public Date getCtime() {return ctime;}public void setCtime(Date ctime) {this.ctime = ctime;}public Date getMtime() {return mtime;}public void setMtime(Date mtime) {this.mtime = mtime;}public Category getCategorys() {return categorys;}public void setCategorys(Category categorys) {this.categorys = categorys;}public Set<Category> getCategory() {return category;}public void setCategory(Set<Category> category) {this.category = category;}@Overridepublic String toString() {return "Category [id=" + id + ", name=" + name + ", description=" + description + ", path=" + path + ", status="+ status + ", ctime=" + ctime + ", mtime=" + mtime + ", categorys=" + categorys + ", category="+ category + "]";}}

期望结果

CREATE TABLE `category` (`id` int(11) NOT NULL AUTO_INCREMENT,`ctime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '',`description` varchar(255) DEFAULT NULL,`mtime` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '',`name` varchar(255) DEFAULT NULL,`path` varchar(255) DEFAULT NULL,`status` enum('Enabled','Disabled') DEFAULT 'Enabled' COMMENT '',`pid` int(11) DEFAULT NULL,PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8

12.2.为字段增加索引

我们希望为 name 和 path 字段增加普通索引

package common.domain;import java.util.Date;import java.util.Set;import javax.persistence.CascadeType;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.FetchType;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.Index;import javax.persistence.JoinColumn;import javax.persistence.ManyToOne;import javax.persistence.OneToMany;import javax.persistence.Table;import org.springframework.format.annotation.DateTimeFormat;import com.fasterxml.jackson.annotation.JsonFormat;import com.fasterxml.jackson.annotation.JsonIgnore;@Entity@Table(indexes = { @Index(name = "name", columnList = "name DESC"), @Index(name = "path", columnList = "path") })public class Category {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "id", unique = true, nullable = false, insertable = true, updatable = false)public int id;public String name;public String description;public String path;@Column(columnDefinition = "enum('Enabled','Disabled') DEFAULT 'Enabled' COMMENT '状态'")public String status;@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")@Column(columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间'")public Date ctime;@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")@Column(columnDefinition = "TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更改时间'")public Date mtime;@ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })@JoinColumn(name = "pid", referencedColumnName = "id")private Category categorys;@JsonIgnore@OneToMany(cascade = CascadeType.ALL, mappedBy = "category", fetch = FetchType.EAGER)private Set<Category> category;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}public String getPath() {return path;}public void setPath(String path) {this.path = path;}public String getStatus() {return status;}public void setStatus(String status) {this.status = status;}public Date getCtime() {return ctime;}public void setCtime(Date ctime) {this.ctime = ctime;}public Date getMtime() {return mtime;}public void setMtime(Date mtime) {this.mtime = mtime;}public Category getCategorys() {return categorys;}public void setCategorys(Category categorys) {this.categorys = categorys;}public Set<Category> getCategory() {return category;}public void setCategory(Set<Category> category) {this.category = category;}@Overridepublic String toString() {return "Category [id=" + id + ", name=" + name + ", description=" + description + ", path=" + path + ", status="+ status + ", ctime=" + ctime + ", mtime=" + mtime + ", categorys=" + categorys + ", category="+ category + "]";}}

期望结果

CREATE TABLE `category` (`id` int(11) NOT NULL AUTO_INCREMENT,`ctime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '????',`description` varchar(255) DEFAULT NULL,`mtime` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '????',`name` varchar(255) DEFAULT NULL,`path` varchar(255) DEFAULT NULL,`status` enum('Enabled','Disabled') DEFAULT 'Enabled' COMMENT '??',`pid` int(11) DEFAULT NULL,PRIMARY KEY (`id`),KEY `name` (`name`),KEY `path` (`path`),KEY `FKeiel7nqjxu4kmefso9tm9qcsu` (`pid`),CONSTRAINT `FKeiel7nqjxu4kmefso9tm9qcsu` FOREIGN KEY (`pid`) REFERENCES `category` (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8

12.3.复合索引

创建由多个字段组成的复合索引,如: "member_id", "articleId"

package killer.api.model;import java.io.Serializable;import java.util.Date;import javax.persistence.CascadeType;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.ManyToOne;import javax.persistence.Table;import javax.persistence.Temporal;import javax.persistence.TemporalType;import javax.persistence.UniqueConstraint;import com.fasterxml.jackson.annotation.JsonFormat;@Entity@Table(name = "comment", uniqueConstraints = { @UniqueConstraint(columnNames = { "member_id", "articleId" }) })public class Comment implements Serializable {/*** */private static final long serialVersionUID = -1484408775034277681L;@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "id", unique = true, nullable = false, insertable = true, updatable = false)private int id;@ManyToOne(cascade = { CascadeType.ALL })@JoinColumn(name = "member_id")private Member member;private int articleId;private String message;@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")@Temporal(TemporalType.TIMESTAMP)@Column(updatable = false)@org.hibernate.annotations.CreationTimestampprotected Date createDate;public int getId() {return id;}public void setId(int id) {this.id = id;}public Member getMember() {return member;}public void setMember(Member member) {this.member = member;}public int getArticleId() {return articleId;}public void setArticleId(int articleId) {this.articleId = articleId;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}public Date getCreateDate() {return createDate;}public void setCreateDate(Date createDate) {this.createDate = createDate;}}

期望结果

CREATE TABLE `comment` (`id` int(11) NOT NULL AUTO_INCREMENT,`article_id` int(11) NOT NULL,`create_date` datetime DEFAULT NULL,`message` varchar(255) DEFAULT NULL,`member_id` int(11) DEFAULT NULL,PRIMARY KEY (`id`),UNIQUE KEY `UK5qxfiu92nwlvgli7bl3evl11m` (`member_id`,`article_id`),CONSTRAINT `FKmrrrpi513ssu63i2783jyiv9m` FOREIGN KEY (`member_id`) REFERENCES `member` (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;

12.4.一对多实例

如下图,我们将实现 categroy 和 article 的一对多关系

+-----------+| category ||-----------|+-->|id | <---+| |title||| |description| 1:n| |status||| |parent_id | o---+| +-----------+|1:n|| +-----------------+ +-----------------+| | article | | feedback || |-----------------| |-----------------|| |id|<--1:n--+ |id|| |title | | |title || |content| | |content|| |datetime | | |datetime || |status | | |status |+--o|category_id| +--o|article_id |+--o|member_id | +-->|member_id || +-----------------+ | +-----------------+| | ,, | | | ,, || +-----------------+ | +-----------------+||1:n +----------++---1:n---+| | member ||| |----------||+-->|id | <---+|user||passwd ||nickname ||status |+----------+

首先定义分类实体类

package common.domain;import java.util.Date;import java.util.Set;import javax.persistence.CascadeType;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.FetchType;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.Index;import javax.persistence.JoinColumn;import javax.persistence.ManyToOne;import javax.persistence.OneToMany;import javax.persistence.Table;import org.springframework.format.annotation.DateTimeFormat;import com.fasterxml.jackson.annotation.JsonFormat;import com.fasterxml.jackson.annotation.JsonIgnore;@Entity@Table(indexes = { @Index(name = "name", columnList = "name DESC"), @Index(name = "path", columnList = "path") })public class Category {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "id", unique = true, nullable = false, insertable = true, updatable = false)public int id;public String name;public String description;public String path;@Column(columnDefinition = "enum('Enabled','Disabled') DEFAULT 'Enabled' COMMENT '状态'")public String status;@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")@Column(columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间'")public Date ctime;@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")@Column(columnDefinition = "TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更改时间'")public Date mtime;@ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })@JoinColumn(name = "pid", referencedColumnName = "id")private Category categorys;@JsonIgnore@OneToMany(cascade = CascadeType.ALL, mappedBy = "category", fetch = FetchType.EAGER)private Set<Category> category;@JsonIgnore@OneToMany(cascade = CascadeType.ALL, mappedBy = "category", orphanRemoval = true)private Set<Article> article;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}public String getPath() {return path;}public void setPath(String path) {this.path = path;}public String getStatus() {return status;}public void setStatus(String status) {this.status = status;}public Date getCtime() {return ctime;}public void setCtime(Date ctime) {this.ctime = ctime;}public Date getMtime() {return mtime;}public void setMtime(Date mtime) {this.mtime = mtime;}public Category getCategorys() {return categorys;}public void setCategorys(Category categorys) {this.categorys = categorys;}public Set<Category> getCategory() {return category;}public void setCategory(Set<Category> category) {this.category = category;}@Overridepublic String toString() {return "Category [id=" + id + ", name=" + name + ", description=" + description + ", path=" + path + ", status="+ status + ", ctime=" + ctime + ", mtime=" + mtime + ", categorys=" + categorys + ", category="+ category + "]";}}

定义文章实体类

package common.domain;import java.io.Serializable;import java.util.Date;import java.util.Set;import javax.persistence.CascadeType;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.FetchType;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.ManyToOne;import javax.persistence.OneToMany;import javax.persistence.Table;import org.springframework.format.annotation.DateTimeFormat;import com.fasterxml.jackson.annotation.JsonFormat;import com.fasterxml.jackson.annotation.JsonIgnore;@Entity@Table(name = "article")public class Article implements Serializable {private static final long serialVersionUID = 7603772682950271321L;@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "id", unique = true, nullable = false, insertable = true, updatable = false)public int id;public String title;@Column(name = "short")public String shortTitle;public String description;public String author;public int star;public String tag;public boolean share;public boolean status;public String content;@ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })@JoinColumn(name = "category_id", referencedColumnName = "id")private Category category;@ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })@JoinColumn(name = "site_id", referencedColumnName = "id")private Site site;@ManyToOne(cascade = { CascadeType.ALL })@JoinColumn(name = "member_id", referencedColumnName = "id")private Member member;@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")@Column(columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间'")public Date ctime;@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")@Column(columnDefinition = "TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更改时间'")public Date mtime;@JsonIgnore@OneToMany(cascade = CascadeType.ALL, mappedBy = "article", fetch = FetchType.EAGER)private Set<Comment> comment;@JsonIgnore@OneToMany(cascade = CascadeType.ALL, mappedBy = "article", fetch = FetchType.EAGER)private Set<Favorites> favorites;@JsonIgnore@OneToMany(cascade = CascadeType.ALL, mappedBy = "article", orphanRemoval = true)private Set<Statistics> statistics;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}public Date getCtime() {return ctime;}public void setCtime(Date ctime) {this.ctime = ctime;}public String getShortTitle() {return shortTitle;}public void setShortTitle(String shortTitle) {this.shortTitle = shortTitle;}public String getAuthor() {return author;}public void setAuthor(String author) {this.author = author;}public int getStar() {return star;}public void setStar(int star) {this.star = star;}public String getTag() {return tag;}public void setTag(String tag) {this.tag = tag;}public boolean isShare() {return share;}public void setShare(boolean share) {this.share = share;}public boolean isStatus() {return status;}public void setStatus(boolean status) {this.status = status;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}public Category getCategory() {return category;}public void setCategory(Category category) {this.category = category;}public Member getMember() {return member;}public void setMember(Member member) {this.member = member;}public Set<Comment> getComment() {return comment;}public void setComment(Set<Comment> comment) {ment = comment;}public Set<Favorites> getFavorites() {return favorites;}public void setFavorites(Set<Favorites> favorites) {this.favorites = favorites;}public Set<Statistics> getStatistics() {return statistics;}public void setStatistics(Set<Statistics> statistics) {this.statistics = statistics;}public Site getSite() {return site;}public void setSite(Site site) {this.site = site;}public Date getMtime() {return mtime;}public void setMtime(Date mtime) {this.mtime = mtime;}@Overridepublic String toString() {return "Article [id=" + id + ", title=" + title + ", shortTitle=" + shortTitle + ", description=" + description+ ", author=" + author + ", star=" + star + ", tag=" + tag + ", share=" + share + ", status=" + status+ ", content=" + content + ", category=" + category + ", site=" + site + ", member=" + member+ ", ctime=" + ctime + ", mtime=" + mtime + ", comment=" + comment + ", favorites=" + favorites+ ", statistics=" + statistics + "]";}}

希望结果

CREATE TABLE `category` (`id` int(11) NOT NULL AUTO_INCREMENT,`ctime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '????',`description` varchar(255) DEFAULT NULL,`mtime` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '????',`name` varchar(255) DEFAULT NULL,`path` varchar(255) DEFAULT NULL,`status` enum('Enabled','Disabled') DEFAULT 'Enabled' COMMENT '??',`pid` int(11) DEFAULT NULL,PRIMARY KEY (`id`),KEY `name` (`name`),KEY `path` (`path`),KEY `FKeiel7nqjxu4kmefso9tm9qcsu` (`pid`),CONSTRAINT `FKeiel7nqjxu4kmefso9tm9qcsu` FOREIGN KEY (`pid`) REFERENCES `category` (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;CREATE TABLE `article` (`id` int(11) NOT NULL AUTO_INCREMENT,`author` varchar(255) DEFAULT NULL,`content` varchar(255) DEFAULT NULL,`ctime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '????',`description` varchar(255) DEFAULT NULL,`mtime` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '????',`share` bit(1) NOT NULL,`short` varchar(255) DEFAULT NULL,`star` int(11) NOT NULL,`status` bit(1) NOT NULL,`tag` varchar(255) DEFAULT NULL,`title` varchar(255) DEFAULT NULL,`category_id` int(11) DEFAULT NULL,`member_id` int(11) DEFAULT NULL,`site_id` int(11) DEFAULT NULL,PRIMARY KEY (`id`),KEY `FKy5kkohbk00g0w88fi05k2hcw` (`category_id`),KEY `FK6l9vkfd5ixw8o8kph5rj1k7gu` (`member_id`),KEY `FKrxbc33rok9m4n6pnbbwb3piwf` (`site_id`),CONSTRAINT `FK6l9vkfd5ixw8o8kph5rj1k7gu` FOREIGN KEY (`member_id`) REFERENCES `member` (`id`),CONSTRAINT `FKrxbc33rok9m4n6pnbbwb3piwf` FOREIGN KEY (`site_id`) REFERENCES `site` (`id`),CONSTRAINT `FKy5kkohbk00g0w88fi05k2hcw` FOREIGN KEY (`category_id`) REFERENCES `category` (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;

现在我们已经将 categroy 与 article 两张表一对多关系建立起来。

12.5.ManyToMany 多对多

用户与角色就是一个多对多的关系,多对多是需要中间表做关联的。所以需要一个 user_has_role 表。

+----------++---------------+ +--------+| users || user_has_role | | role |+----------++---------------+ +--------+| id | <------o | user_id |/---> | id|| name|| role_id | o---+| name || password ||| | |+----------++---------------+ +--------+

创建 User 表

package killer.api.domain.test;import java.io.Serializable;import java.util.Set;import javax.persistence.Entity;import javax.persistence.FetchType;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.JoinTable;import javax.persistence.ManyToMany;import javax.persistence.Table;import javax.persistence.JoinColumn;@Entity@Table(name = "users")public class Users implements Serializable {/*** */private static final long serialVersionUID = -2480194112597046349L;@Id@GeneratedValue(strategy = GenerationType.AUTO)private int id;private String name;private String password;@ManyToMany(fetch = FetchType.EAGER)@JoinTable(name = "user_has_role", joinColumns = { @JoinColumn(name = "user_id", referencedColumnName = "id") }, inverseJoinColumns = { @JoinColumn(name = "role_id", referencedColumnName = "id") })private Set<Roles> roles;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public Set<Roles> getRoles() {return roles;}public void setRoles(Set<Roles> roles) {this.roles = roles;}@Overridepublic String toString() {return "Users [id=" + id + ", name=" + name + ", password=" + password + ", roles=" + roles + "]";}}

创建 Role 表

package killer.api.domain.test;import java.io.Serializable;import java.util.Set;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.ManyToMany;import javax.persistence.Table;@Entity@Table(name = "roles")public class Roles implements Serializable {private static final long serialVersionUID = 6737037465677800326L;@Id@GeneratedValue(strategy = GenerationType.AUTO)private int id;private String name;@ManyToMany(mappedBy = "roles")private Set<Users> users;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Set<Users> getUsers() {return users;}public void setUsers(Set<Users> users) {this.users = users;}@Overridepublic String toString() {return "Roles [id=" + id + ", name=" + name + ", users=" + users + "]";}}

最终产生数据库表如下

CREATE TABLE `users` (`id` INT(11) NOT NULL AUTO_INCREMENT,`name` VARCHAR(255) NULL DEFAULT NULL,`password` VARCHAR(255) NULL DEFAULT NULL,PRIMARY KEY (`id`))COLLATE='utf8_general_ci'ENGINE=InnoDB;CREATE TABLE `roles` (`id` INT(11) NOT NULL AUTO_INCREMENT,`name` VARCHAR(255) NULL DEFAULT NULL,PRIMARY KEY (`id`))COLLATE='utf8_general_ci'ENGINE=InnoDB;CREATE TABLE `user_has_role` (`user_id` INT(11) NOT NULL,`role_id` INT(11) NOT NULL,PRIMARY KEY (`user_id`, `role_id`),INDEX `FKsvvq61v3koh04fycopbjx72hj` (`role_id`),CONSTRAINT `FK2dl1ftxlkldulcp934i3125qo` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`),CONSTRAINT `FKsvvq61v3koh04fycopbjx72hj` FOREIGN KEY (`role_id`) REFERENCES `roles` (`id`))COLLATE='utf8_general_ci'ENGINE=InnoDB;

12.6.外键级联删除

orphanRemoval = true 可以实现数据级联删除

package killer.api.domain;import java.io.Serializable;import java.util.Set;import javax.persistence.CascadeType;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.Id;import javax.persistence.OneToMany;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Table;import com.fasterxml.jackson.annotation.JsonIgnore;@Entity@Table(name = "member")public class Member implements Serializable {/*** */private static final long serialVersionUID = 1L;@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "id", unique = true, nullable = false, insertable = true, updatable = false)private int id;private String name;private String sex;private int age;private String wechat;@Column(unique = true)private String mobile;private String picture;private String ipAddress;@JsonIgnore@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "member")private Set<Comment> comment;@JsonIgnore@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "member")private Set<StatisticsHistory> statisticsHistory;public Member() {}public Member(int id) {this.id = id;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getWechat() {return wechat;}public void setWechat(String wechat) {this.wechat = wechat;}public String getMobile() {return mobile;}public void setMobile(String mobile) {this.mobile = mobile;}public String getPicture() {return picture;}public void setPicture(String picture) {this.picture = picture;}public String getIpAddress() {return ipAddress;}public void setIpAddress(String ipAddress) {this.ipAddress = ipAddress;}@Overridepublic String toString() {return "Member [id=" + id + ", name=" + name + ", sex=" + sex + ", age=" + age + ", wechat=" + wechat + ", mobile=" + mobile + ", picture=" + picture + ", ipAddress=" + ipAddress + "]";}}

相关文章:

找到并留住最佳员工

让程序猿和攻城狮更敬业

攻城狮的自我营销 人力资源管理·培训与开发

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。