前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >hibernate 一对一,一对多,多对多关联关系使用

hibernate 一对一,一对多,多对多关联关系使用

作者头像
用户5166330
发布2019-04-16 17:58:49
5.1K0
发布2019-04-16 17:58:49
举报
文章被收录于专栏:帅哥哥写代码帅哥哥写代码
关系型数据库

关系数据库,是建立在关系模型基础上的数据库,借助于集合代数等数学概念和方法来处理数据库中的数据。现实世界中的各种实体以及实体之间的各种联系均用关系模型来表示。关系模型是由埃德加·科德于1970年首先提出的,并配合“科德十二定律”。现如今虽然对此模型有一些批评意见,但它还是数据存储的传统标准。标准数据查询语言SQL就是一种基于关系数据库的语言,这种语言执行对关系数据库中数据的检索和操作。 关系模型由关系数据结构、关系操作集合、关系完整性约束三部分组成。 简单说,关系型数据库是由多张能互相联接的二维行列表格组成的数据库。

一对一关系处理

one class

代码语言:javascript
复制
package com.example.demo.entity.onetoone;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;

import lombok.Getter;
import lombok.Setter;

@Entity
@Getter
@Setter
public class One {

  @Id
  @GeneratedValue
  private String id;
  private String name;

  @OneToOne
  private Two two;
}

two class

代码语言:javascript
复制
@Entity
@Getter
@Setter
public class Two {

  @Id
  @GeneratedValue
  private String id;
  private String name;

}

默认建表结构

一对一

一对一 如果我们只是单纯的在两个实体类中分别加上@OneToOne注解,会发现两张表都分别引入了对方的主键作为外键。明显的数据冗余,毕竟关系不用双方存储。 利用mappedBy属性,指明关系由哪一方维护。

一对多关系处理

创建两个实体对象,分别对应一与多的一方。 情况1-只在多的一方在@ManyToOne注解 one方

代码语言:javascript
复制
package com.example.demo.entity.onetomany;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

import lombok.Getter;
import lombok.Setter;

@Entity
@Getter
@Setter
public class OneObject {

  @Id
  @GeneratedValue
  private String id;
  private String name;
  
}

many方

代码语言:javascript
复制
package com.example.demo.entity.onetomany;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

import lombok.Getter;
import lombok.Setter;

@Entity
@Getter
@Setter
public class OneObject {

  @Id
  @GeneratedValue
  private String id;
  private String name;
  
}

此时我只在多的一方加了一个ManyToOne注解。生成表结构关系如下

只有ManyToOne一个注解 默认是在many_object里面加了一个外键列

只有ManyToOne列属性 情况2-只在one的一方加

只有一个OneToMany注解 默认情况下是生成了一张关系表。用户维护一对多关系。

关系表 至于默认的表名列名,大家可以去看生成规则。不在这篇文章研究范围。 情况3-不想生成关系表,想通过列名维护。 此时使用@JoinColumn属性。 one方

代码语言:javascript
复制
  @OneToMany
  @JoinColumn(name="obj_id")
  private List<ManyObject> manyObject;

many方

代码语言:javascript
复制
 @ManyToOne(fetch=FetchType.EAGER,cascade=CascadeType.ALL)
  @JoinColumn(name="obj_id")
  private OneObject object;

加上@JoinColumn属性表结构

扩展

在一对多双方都设置了关联关系后,进行数据存储模拟

代码语言:javascript
复制
  @Test
  public void contextLoads() {
      OneObject object = new OneObject("1");
      
      object.setManyObject(new ArrayList<ManyObject>()); 
      ManyObject manyObject = new ManyObject("ysh");
      ManyObject manyObject2 = new ManyObject("ysh2");
      object.getManyObject().add(manyObject);
      object.getManyObject().add(manyObject2);
      mp.save(manyObject);
      mp.save(manyObject2);
      op.save(object);                
  }

控制端打印sql如下 除了三条insert数据。还有两条update语句。这个很好理解。先插入多的一方数据,然后在把one对应的一方关联加进去。 想要避免这种多余sql。有两种方式。 方法一:直接把one对应的一方赋值给多的一方。(上面是把多的一方赋值给one的一方

代码语言:javascript
复制
  public void contextLoads() {
      OneObject object = new OneObject("1");
      
      object.setManyObject(new ArrayList<ManyObject>()); 
      ManyObject manyObject = new ManyObject("ysh");
      ManyObject manyObject2 = new ManyObject("ysh2");
      manyObject.setObject(object);
      manyObject2.setObject(object);
//     object.getManyObject().add(manyObject);
//     object.getManyObject().add(manyObject2);
      op.save(object);
      mp.save(manyObject);
      mp.save(manyObject2);
  }

控制台日志 可以看到update语句已经没有了。 方法二:利用OneToMany注解里面的mappedBy属性 @OneToMany(mappedBy = "object") // @OneToMany // @JoinColumn(name="obj_id") private List<ManyObject> manyObject; 注意mappedBy不能与@JoinColumn注解连用

利用mappedBy属性后的输出 可以看到也实现了减少两条sql的功能。算是小功能优化。

多对多

正常建立两个多对多关系实体 1.多对多实体一

代码语言:javascript
复制
package com.example.demo.entity.manytomany;

import java.util.List;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@Entity
public class Manyone {
  @Id
  @GeneratedValue
  private Long id;
  private String name;
  
  @ManyToMany
  private List<Manytwo> manytwos;
}

多对多实体二

代码语言:javascript
复制
package com.example.demo.entity.manytomany;

import java.util.List;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@Entity
public class Manytwo {

  @Id
  @GeneratedValue
  private Long id;
  private String name;
  
  @ManyToMany
  private List<Manyone> manyones;
}

表结构 很显然的关系表冗余。 利用@ManyToMany(mappedBy="manytwos")的mappedBy属性将关系表改为由一端维护。生成表结构如下:

表结构

cascade属性

代码语言:javascript
复制
public enum CascadeType { 

   /** Cascade all operations */
   ALL, 

   /** Cascade persist operation */
  PERSIST, 

   /** Cascade merge operation */
   MERGE, 

   /** Cascade remove operation */
   REMOVE,

   /** Cascade refresh operation */
   REFRESH,

  /**
    * Cascade detach operation
    *
    * @since Java Persistence 2.0
    * 
    */   
   DETACH
}

fetch属性

FetchType.LAZY:懒加载,加载一个实体时,定义懒加载的属性不会马上从数据库中加载。 FetchType.EAGER:急加载,加载一个实体时,定义急加载的属性会立即从数据库中加载。

结语

本文属于基础篇。觉得不错也可以点亮下方小星星。

本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.01.18 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 关系型数据库
  • 一对一关系处理
  • 一对多关系处理
  • 扩展
  • 多对多
  • cascade属性
  • fetch属性
  • 结语
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com