最近做的项目中遇到很多各种表间关系是一对多对应的问题,开始自己弄的时候就去网上查,结果发现网上有关这方面的东西给的不是自己想要的,于是经过几天不停的更改测试终于算是勉强完成了级联更新的问题。在此把它记录下来以便日后复用
先描述下问题。一个用户表tb_app_user,一个职业技能表tb_app_wl,一个特殊技能表tb_app_special,关系为用户表和职业技能表时一对一的关系,而一个职业技能表包含多个特殊技能即为一对多的关系。其实简单的只拿职业技能表和特殊技能表来说明问题就好。问题是在实际项目中职业技能表不可能单独存在,他必须需要关联自己的用户。因此还是把tb_app_user也拿出来了。如图为指导关系。
用户在注册后会自动拥有这张tb_app_wl的表格,而tb_app_wl中也会包含三个tb_app_special,这种使用Hibernate中的级联操作很简单就可以实现。
持久类User:
@Entity(name = "TB_APP_USER") @SelectBeforeUpdate(value = true) @OptimisticLocking(type = OptimisticLockType.VERSION) @Polymorphism(type = PolymorphismType.EXPLICIT) @GenericGenerator(name = "systemUUID", strategy = "uuid") public class User extends BaseObject { private static final long serialVersionUID = -3027223712328553788L; public static String user_name = "name"; @Id @GeneratedValue(generator = "systemUUID") @Column(name = "ID") private String id; @OneToOne(mappedBy = "user", cascade = CascadeType.PERSIST) private WL wl; public WL getWl() { return wl; } public void setWl(WL wl) { this.wl = wl; } public String getSysId() { return id; } public void setSysId(String sysId) { this.id = sysId; } }
cascade=CascadeType.PERSIST的意思是在执行persist()这个方法的时候会级联执行与他关联的数据插入操作。简单来说就是我注册一个用户User后,关联它的职业技能也会创建。下面列出WL持久类的实例
@Entity @Table(name = "tb_app_wl", catalog = "hrborse") @GenericGenerator(name = "wl", strategy = "uuid") public class WL extends BaseObject { private static final long serialVersionUID = 1L; private String id; private User user;private Set<Special> speciallist = new HashSet<Special>(); @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "wl") public Set<Special> getSpeciallist() { return speciallist; } public void setSpeciallist(Set<Special> speciallist) { this.speciallist = speciallist; } @Id @GeneratedValue(generator = "wl") @Column(name = "id") public String getId() { return this.id; } public void setId(String id) { this.id = id; } @OneToOne(cascade = CascadeType.ALL) @JoinColumn(name = "user_id") public User getUser() { return this.user; } public void setUser(User user) { this.user = user; } }
持久类 Special
@Entity @Table(name = "tb_app_special", catalog = "hrborse") @GenericGenerator(name = "special", strategy = "uuid") public class Special extends BaseObject { private static final long serialVersionUID = 1L; private String id; private WL wl; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "wl_id") public WL getWl() { return wl; } public void setWl(WL wl) { this.wl = wl; } @Id @GeneratedValue(generator = "special") @Column(name = "id") public String getId() { return this.id; } public void setId(String id) { this.id = id; } }
然后把执行级联操作代码贴出来
public String register() { User user = new User(); user.setName(name); user.setEmail(email); user.setModifiedBy("SYS"); WL wl = new WL(); Set<Special> specialList = new HashSet<Special>(); Special special1 = new Special(); Special special2 = new Special(); Special special3 = new Special(); special1.setWl(wl); special2.setWl(wl); special3.setWl(wl); specialList.add(special1); specialList.add(special2); specialList.add(special3); wl.setUser(user); wl.setSpeciallist(specialList); user.setWl(wl); userService.registerUser(user); return SUCCESS; }
注意set方法的对应,这样子在注册一个用户后就数据库里也会拥有wl和special的数据,他们都拥有主键以及关联的外键,但是其他数据都是null,接下来就是更新着写null的数据,拿我们的新数据update,对于wl,我们登录后可以由:user.getWl().getId获得,但是无法获得special因为它是多个属性不可能从这里获取,所以需要按照special关联的外键wl_id查出所有的special,然后遍历放入相应的wl属性中,最后只对wl进行更新便可完成对其对应special的更新,这样的好处就是用户单击保存信息后不会无限创建新表了。
public String saveWL() { User user = (User) session.get("user"); int count=0; Set<Special> listspecial = new HashSet<Special>(); wl.setId(user.getWl().getId()); wl.setUser(user); wl.setWSw(wsw); wl.setSkillCertificate(skillcertificate); wl.setCertificate(certificate); wl.setLanguage(language); wl.setLiteracy(literacy); wl.setListenSkill(listenskill); String id = wl.getId(); List<Special> lis = wlService.findSpecialListById(id); for (Special specials : lis) { if(count==0){ special.setId(specials.getId()); special.setWl(wl); listspecial.add(special); } if(count==1){ special2.setId(specials.getId()); special2.setWl(wl); listspecial.add(special2); } if(count==2){ special3.setId(specials.getId()); special3.setWl(wl); listspecial.add(special3); } count++; } wl.setSpeciallist(listspecial); user.setWl(wl); wlService.updateWL(user.getWl()); return SUCCESS; }