环境
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方法
}
这样配置,在查询的时候,就不会嵌套了。
值得一提的是,这里所有的配置都是最基础的,如果需要考虑性能问题,还是要写懒加载的。