Hibernate JPA 之关联映射

来源:互联网 发布:创意艺术大学吧 知乎 编辑:程序博客网 时间:2024/06/05 15:20

一对多

  • 一方
@Entity@Table(name="test_user")public class User {private String id;private List<LoginHistory> loginHistories;@Id@GeneratedValue(generator = "uuid-gen")@GenericGenerator(name = "uuid-gen", strategy = "uuid")@Column(name ="id",length=32)public String getId() {    return id;}public void setId(String id) {    this.id = id;}@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "user")public List<LoginHistory> getLoginHistories() {    return loginHistories;}public void setLoginHistories(List<LoginHistory> loginHistories) {    this.loginHistories = loginHistories;}}

以上是一方的配置,mappedBy=”被维护端外键属性”,mappedBy指明两个关联的实体Bean中,被维护方的外键属性。只能配置在一方,即关系维护方。

多方

@Entity@Table(name="test_login_history")public class LoginHistory {private String id;@Id@GeneratedValue(generator = "uuid-gen")@GenericGenerator(name = "uuid-gen", strategy = "uuid")@Column(name ="id",length=32)public String getId() {    return id;}public void setId(String id) {    this.id = id;}@ManyToOne(cascade = { CascadeType.REFRESH, CascadeType.MERGE,}, optional = true)@JoinColumn(name = "user_id",nullable=true) public User getUser() {    return user;}public void setUser(User user) {    this.user = user;}}

一对多操作实例

@RequestMapping("login")public String login(User user,ModelMap map){    LoginHistory loginHistory=new LoginHistory();    Date d=new Date();    SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");    String datestr=sdf.format(d);    //NO.1 为多方设置外键属性(即一方的实体)    loginHistory.setUser(user);    loginHistory.setLoginDate(datestr);    loginHistory.setLoginIP("127.0.0.1");    List<LoginHistory> lhlist=new ArrayList<LoginHistory>();    lhlist.add(loginHistory);    //NO.2 将多方的实体,赋值给一方    user.setLoginHistories(lhlist);    //NO.3 只保存一方对象,即可级联保存。    userService.addUser(user);    map.put("status", "success");    return "welcome";    }

许多新手配置时,只有关键的NO.2,NO.3 没有设置NO.1 ,这导致数据库,只保存了一方的实体,而没有级联保存多方的实体。

多对多

下面以User和Role为例子,介绍下多对多。直接上代码了,请自行阅读。

@Entity@Table(name="test_user")public class User {private String id;@Id@GeneratedValue(generator = "uuid-gen")@GenericGenerator(name = "uuid-gen", strategy = "uuid")@Column(name ="id",length=32)public String getId() {    return id;}public void setId(String id) {    this.id = id;}private List<Role> roles;/*  joinColumns写的是本表在中间表的外键名称,  inverseJoinColumns写的是另一个表在中间表的外键名称。 */@ManyToMany(fetch = FetchType.LAZY)@JoinTable(name = "fc_role_user", joinColumns = @JoinColumn(name = "fk_user_id"), inverseJoinColumns = @JoinColumn(name = "fk_role_id"))public List<Role> getRoles() {    return roles;}public void setRoles(List<Role> roles) {    this.roles = roles;}}@Entity@Table(name="test_role")public class Role {    private String id;//角色id    private String rolename;//角色名称    private List<User> users;    @Id    @GeneratedValue(generator = "uuid-gen")    @GenericGenerator(name = "uuid-gen", strategy = "uuid")    @Column(name ="id",length=32)    public String getId() {        return id;    }    public void setId(String id) {        this.id = id;    }    @Column(name="role_name",length=50)    public String getRolename() {        return rolename;    }    public void setRolename(String rolename) {        this.rolename = rolename;    }    @ManyToMany(fetch = FetchType.LAZY,cascade={CascadeType.PERSIST,CascadeType.MERGE},mappedBy = "roles")    public List<User> getUsers() {        return users;    }    public void setUsers(List<User> users) {        this.users = users;    }}// 多对多保存实例【controller】    @RequestMapping("login")    public String login(User user,ModelMap map){        Role role=null;        role=roleService.getRoleByName("admin2");        if(role==null){            role=new Role();            role.setRolename("admin2");            roleService.addRole(role);        }        List<Role> rolelist=new ArrayList<Role>();        rolelist.add(role);        user.setRoles(rolelist);        userService.saveUser(user);        return "welcome";    }

关于多对多的维护端和被维护端,如何确定,我要啰嗦几句。之前因为搞不明白,没少让坑。网上关于维护端和被维护的介绍,大都一笔带过,而且概念模糊,对本人开发,造成了很大的误导。我经过实践,总结如下:
所谓的维护端,就是级联关系的主导方,一般对应多对多关系中“少数”一方,何为“少数”,就拿上边的例子解释,一个系统可以有几万个用户,但角色肯定不会也是几万个,最多也就是十几个,那么角色就是“少数”方,也就是维护方。你的级联属性,要在“少数”方配置,级联保存的时候,你可以直接将少数方,作为一个常用属性,赋值给多的一方,直接保存多的一方,你们之间的关系,也就被保存了。

0 0