@ManyToOne与@OneToMany | Spring Data JPA 多表查询

环境

Spring Boot : 2.1.14
Java : 1.8.3
IDEA : 2018.3.3


本文默认已经使用Spring Boot + Spring Data JPA 搭建好数据库层,DAO类已经编写完毕。
首先介绍下面要用到的两个表:subarea 和 subarea_set 表,其中 subarea 与 subarea_set 的关系是一对多的关系。subarea_set 中存在 subarea 的外键 subarea_id。
subarea 表对应的Java实体类如下:

@Entity
public class Subarea {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private long id;

  // 省略其他属性和getter,setter方法  
}

subarea_set 表对用的Java实体类如下:

@Entity
public class SubareaSet {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private long id;
  private long subareaId;

  // 省略其他属性和getter,setter方法 
}

只使用@OneToMany

如果想要在查询 subarea 的时候得到相对应的 subarea_set 的值。如在查询 id = 1 的 subarea 的时候,想要同时得到 subarea_id = 1 subarea_set 的信息,就要使用@OneToMany注解。下面是只是用@OneToMany的情况:
Subarea 类修改如下:

@Entity
public class Subarea {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private long id;
  // 新增
  @OneToMany
  @JoinColumn(name = "subareaId")
  private List<SubareaSet> subareaSetList;
  // 省略其他属性和getter,setter方法  
}

SubareaSet 类不变:

@Entity
public class SubareaSet {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private long id;
  private long subareaId;

  // 省略其他属性和getter,setter方法 
}

这样写,再通过 DAO.findAll() 进行查询,就能同时得到 subarea 和 subarea_set 的信息了。

只使用@ManyToOne

如果在查询 subarea_set 的时候,想要知道 subarea_id 对应的 subarea 的信息(比如 subarea 的 name),那么就可以在 SubareaSet 类中运用 @ManyToOne 注解
Subarea 类不变:

@Entity
public class Subarea {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private long id;

  // 省略其他属性和getter,setter方法  
}

SubareaSet 类修改如下:

@Entity
public class SubareaSet {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private long id;
  //private long subareaId;   不要这个属性
  @ManyToOne
  private Subarea subarea;

  // 省略其他属性和getter,setter方法 
}

值得一提的,在查询时直接使用 DAO.findAll() 方法即可。在插入时,需要按照下面的写法:

SubareaSet subareaSet = new SubareaSet();
Subarea subarea = new Subarea();
subarea.setId(1);     
subareaSet.setSubarea(subarea);
// 其他属性设置

DAO.insert(subareaSet);

同时使用@OneToMany和@ManyToOne

大多数时候我们都是需要两边都配置的。但是两边同时配置显然有一个问题:比如,查询 subarea ,会显示 subareaSetList ,subareaSetList 中的每一项都是 subareaSet ,subareaSet 中又有 subarea ,subarea 中又有 subareaList…这样不就是无限嵌套了嘛。为了解决这个方法,网上有说:增加@JsonIgnore注解。但是这样配置显然是不行的,在查询的时候就是为了能够查询关联表的数据才配置@OneToMany或者@ManyToOne,如果查询不返回了,那配置这个显然就没有意义了。所以正确的做法是使用 @JsonIgnoreProperties 注解

Subarea 类修改如下:

@Entity
public class Subarea {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private long id;

  @OneToMany
  @JsonIgnoreProperties(value = {"subarea"})
  @JoinColumn(name = "subarea_id")
  private List<SubareaSet> subareaSetList;
  // 省略其他属性和getter,setter方法  
}

SubareaSet 类修改如下:

@Entity
public class SubareaSet {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private long id;
  
  @ManyToOne
  @JsonIgnoreProperties(value = {"subareaSetList"})
  private Subarea subarea;

  // 省略其他属性和getter,setter方法 
}

这样配置,在查询的时候,就不会嵌套了。
值得一提的是,这里所有的配置都是最基础的,如果需要考虑性能问题,还是要写懒加载的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值