hibernate使用过程中,必然会使用到 @@OneToMany(一对多) 或者 @ManyToOne(多对一),但是对于这个关系:多对一或者是一对多,到底该由哪一端来维护呢?
主控端:主动维护关系的一端;
被控端:被动维护关系的一端;
在使用注解: @OneToMany或者 @ManyToOne时,往往会带着 :
@OneToMany或者 @ManyToOne 的mappedBy属性,表示该对象为被控端,“多对一”或者“一对多”的关系应该由这一端的另一端(主控端)来维护;如果要更新关联表,则必须使用 cascade={CascadeType.ALL }属性。
看下面的例子:
pojo1:
public class Grain implements java.io.Serializable {
...
private Set<GrainPic> grainPics = new HashSet<GrainPic>(0); //储粮图片
//被控端,主控端对象为GrainPic,通过属性TGrain关联,可以由本对象Grain 级联更新主控对象
@OneToMany(fetch = FetchType.LAZY, mappedBy = "TGrain", cascade = {CascadeType.ALL })
public Set<GrainPic> getGrainPics() {
return this.grainPics;
}
public void setGrainPics(Set<GrainPic> grainPics) {
this.grainPics = grainPics;
}
}
public class GrainPic implements java.io.Serializable {
...
private Grain TGrain;
//主控端对象,多对一的关系由这一端维护,可以直接更新、插入被控端对象Grain 数据,单独保存时,请注意这一点
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "PID")
public Grain getTGrain() {
return this.TGrain;
}
public void setTGrain(Grain TGrain) {
this.TGrain = TGrain;
}
}
控制器执行函数
public Message uploadGrainAndPic(HttpServletRequest req,
String username,
String password,
String lkbm,
String lcbm,
Grain data,
MultipartFile file) {
....
GrainPic pic = new GrainPic(); // 声明并生成主控端对象
pic.setTGrain(data); //主控端维护关系,data 为被控端对象
Set<GrainPic> picSets = new HashSet <GrainPic>();
picSets.add(pic);
data.setGrainPics(picSets); //被控端 级联操作 主控端(如果在pojo中没有写cascade属性,则主控端对象不会被操作,即插入数据)
grainService.save(data);
...
}
执行结果:
Hibernate: insert into t_grain (clxs, container, controlhumiditymeasures, controltemperaturemeasures, dryingmethod, emptybin500pa, fullbin300pa, lcbm, grainheight, grainname, halfemptybin500pa, halffullbin, harvestdate, impurity, indate, innum, reserveperiod, source, storemethod, storetechnology, water) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into t_grain_pic (pid, pic) values (?, ?)
t_grain为被控端表
t_grain_pic为主控端表