一对一关系
新建一个类表示文章内容,其中有一个外键(article_id)关联到文章表(id)
- 文章内容表保存content 大文本
@Entity
@Getter
@Setter
@Table
public class ArticleContent {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String content;
/**
* 关联关系
* name 表示article_content表中外键的名称
* referencedColumnName 表示指向对方 article表中主键名 id
* unique 表示生成的外键索引唯一的
*/
@OneToOne
@JoinColumn(name = "article_id", referencedColumnName = "id", unique = true)
private Article article;
}
- 文章表
@Getter
@Setter
@Entity
@Table
public class Article {
/**
* 主键
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String title;
private String name;
private LocalDateTime createDateTime;
/**
* 关联关系 一对一
* mappedBy 表示维护关系主要让ArticleContent 实体中的article来维护
* cascade 表示级联关系,表示保存article表时同时保存article_content表
*/
@OneToOne(mappedBy = "article",cascade = CascadeType.PERSIST)
private ArticleContent articleContent;
}
建表语句
Hibernate: create table article_content (id integer not null auto_increment, content varchar(255), article_id integer, primary key (id)) engine=InnoDB
Hibernate: alter table article_content drop index UK_9e9uapbfex7ktk3ey108j50j7
Hibernate: alter table article_content add constraint UK_9e9uapbfex7ktk3ey108j50j7 unique (article_id)
Hibernate: alter table article_content add constraint FKr2fwi9p8yrsnwdpuijkai2mx3 foreign key (article_id) references article (id)
测试一对一
@Test
public void one2one(){
//一对一保存测试
Article article=new Article();
article.setCreateDateTime(LocalDateTime.now());
article.setName("felix");
article.setTitle("SpringData Jpa one2one");
ArticleContent content=new ArticleContent();
content.setContent("jpa 实现一对一");
article.setArticleContent(content);
Article save = articleRepository.save(article);
System.out.println(save);
}
过程
Hibernate: insert into article (create_date_time, name, title) values (?, ?, ?)
Hibernate: insert into article_content (article_id, content) values (?, ?)
Article(id=3, title=SpringData Jpa one2one, name=felix, createDateTime=2019-11-04T23:23:36.994620300, articleContent=ArticleContent(id=1, content=jpa 实现一对一, article=null), comments=null)
一对多关系
建立文章评论表
@Getter
@Setter
@Entity
@Table
public class ArticleComment {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String comment;
@ManyToOne
@JoinColumn(name = "article_id",referencedColumnName = "id")
private Article article;
}
在文章Article实体类中添加
@Getter
@Setter
@Entity
@Table
public class Article {
/**
* 主键
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String title;
private String name;
private LocalDateTime createDateTime;
/**
* 关联关系 一对一
* mappedBy 表示维护关系主要让ArticleContent 实体中的article来维护
*/
@OneToOne(mappedBy = "article", cascade = CascadeType.PERSIST)
private ArticleContent articleContent;
/**
* 一对多关系
*/
@OneToMany(mappedBy = "article")
private Set<ArticleComment> comments;
}
测试
@Autowired
private CommentRepository commentRepository;
@Test
public void commentTest() {
Article article = new Article();
article.setCreateDateTime(LocalDateTime.now());
article.setName("felix");
article.setTitle("SpringData Jpa one2many");
ArticleComment comment = new ArticleComment();
comment.setComment("有意思");
ArticleComment comment1 = new ArticleComment();
comment1.setComment("加油");
//建立关系
HashSet<ArticleComment> comments = new HashSet<>();
comments.add(comment);
comments.add(comment1);
article.setComments(comments);
//先保存文章
Article save = articleRepository.save(article);
System.out.println(save);
ArticleComment save1 = commentRepository.save(comment);
System.out.println(save1);
ArticleComment save2 = commentRepository.save(comment1);
System.out.println(save2);
}
执行过程
Hibernate: insert into article (create_date_time, name, title) values (?, ?, ?)
Article(id=2, title=SpringData Jpa one2many, name=felix, createDateTime=2019-11-04T22:54:18.045233, articleContent=null, comments=[ArticleComment(id=null, comment=加油, article=null), ArticleComment(id=null, comment=有意思, article=null)])
Hibernate: insert into article_comment (article_id, comment) values (?, ?)
ArticleComment(id=1, comment=有意思, article=null)
Hibernate: insert into article_comment (article_id, comment) values (?, ?)
ArticleComment(id=2, comment=加油, article=null)
多对多关系
@Getter
@Setter
@Entity
@Table(name = "type")
public class ArticleType {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String type;
/**
* name 中间表名称
*
* joinColumns 中间表对应当前表的主键名称
*
* inverseJoinColumns 中间表对应对方表的主键名称
*/
@ManyToMany
@JoinTable(name = "article_type",
joinColumns = {@JoinColumn(name = "tid",referencedColumnName = "id")},
inverseJoinColumns = {@JoinColumn(name = "aid",referencedColumnName = "id")}
)
private Set<Article> articles;
}
@Getter
@Setter
@Entity
@Table
public class Article {
/**
* 主键
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String title;
private String name;
private LocalDateTime createDateTime;
/**
* 关联关系 一对一
* mappedBy 表示维护关系主要让ArticleContent 实体中的article来维护
*/
@OneToOne(mappedBy = "article", cascade = CascadeType.PERSIST)
private ArticleContent articleContent;
/**
* 一对多关系
*/
@OneToMany(mappedBy = "article")
private Set<ArticleComment> comments;
/**
* 多对多关联
*/
@ManyToMany(mappedBy = "articles")
private Set<ArticleType> types;
}
测试
@Test
public void manytomanyTest() {
Article article = new Article();
article.setCreateDateTime(LocalDateTime.now());
article.setName("felix");
article.setTitle("SpringData Jpa many2many");
Article article1 = new Article();
article1.setCreateDateTime(LocalDateTime.now());
article1.setName("felix");
article1.setTitle("SpringData Jpa many2many");
ArticleType type = new ArticleType();
type.setType("other");
ArticleType type1 = new ArticleType();
type.setType("other1");
HashSet<Article> articles = new HashSet<>();
articles.add(article);
articles.add(article1);
type.setArticles(articles);
HashSet<ArticleType> types = new HashSet<>();
types.add(type);
types.add(type1);
article.setTypes(types);
articleRepository.save(article);
articleRepository.save(article1);
typeRepository.save(type1);
typeRepository.save(type);
}
Hibernate: create table article_type (tid integer not null, aid integer not null, primary key (tid, aid)) engine=InnoDB
Hibernate: create table type (id integer not null auto_increment, type varchar(255), primary key (id)) engine=InnoDB
Hibernate: alter table article_type add constraint FK6rv3y9rl4moi6ipc3ecgw2xnn foreign key (aid) references article (id)
Hibernate: alter table article_type add constraint FK7xbykh632xpgso3js30phx3kc foreign key (tid) references type (id)
Hibernate: insert into article (create_date_time, name, title) values (?, ?, ?)
Hibernate: insert into article (create_date_time, name, title) values (?, ?, ?)
Hibernate: insert into type (type) values (?)
Hibernate: insert into type (type) values (?)
Hibernate: insert into article_type (tid, aid) values (?, ?)
Hibernate: insert into article_type (tid, aid) values (?, ?)
表关联情况

注意
在使用lombok @Data注解会引起 java.lang.StackOverflowError 异常,原因是两个实体进行关联@Data 包含了@ToString,lombok 在生成时会出现循环比较两类中的 hashcode,导致内存溢出。
解决方式:不要使用@Data 改用@Getter、@Setter
本文详细介绍了如何使用 Java Persistence API (JPA) 实现数据库中的一对一、一对多及多对多关系映射,包括实体类定义、关联关系配置及测试示例。

9478

被折叠的 条评论
为什么被折叠?



