1. 前言
感觉JPA关联映射实现感觉比Hibernate配置文件的关联映射几乎一样,只是引入了“零配置”这个概念。劣者自己在做一个东西的时候用到了关联映射,在此将它做一个总结。留给自己回顾用。
2. 需求
现在遇到这么一个简单的需求,要求做一个小小的用户权限管理系统。不同的系统人员属于不同的角色组,不同的角色组有不同的操作权限(细粒度:显示不同的操作菜单)。那么基于以上需求可以得出这样的业务图。
|
1. 建模
从以上业务图我们不难得出以下模型。
UxAdmin:代表用户
UxRole:代表角色组
UxSysMenu:代表系统菜单
得出相关类图如下
UxAdmin(用户)
可以看出里面有一个Set<UxRole>,代表角色实体不能重复,当然判断UxRole是否重复的算法需要在UxRole里自己实现,此为后话暂且不表。
UxRole(角色)
在角色实体中,含有Set<UxAdmin>、Set<UxSysMenu>。也就是说角色相当于用户和菜单的一个中间桥梁,根据用户找到用户的角色,再根据角色才能找到该用户能使用的操作菜单。并且角色组下的用户和菜单都不能重复。
UxSysMenu(菜单)
1. 实体类代码
有了类图,就有了实体类代码了。
UxAdmin
package module.system.vo;
import java.util.Set;
import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.Table;
import org.apache.struts2.json.annotations.JSON;
/** * liuyan */ @Entity @Table(name = "ux_admin") public class UxAdmin implements java.io.Serializable {
// Fields private Integer id; private String admin; private String password; private Set<UxRole> roles;
// Constructors
/** default constructor */ public UxAdmin() { }
/** minimal constructor */ public UxAdmin(Integer id) { this.id = id; }
/** full constructor */ public UxAdmin(Integer id, String admin, String password) { this.id = id; this.admin = admin; this.password = password; }
// Property accessors @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "id", unique = true, nullable = false) public Integer getId() { return this.id; }
public void setId(Integer id) { this.id = id; }
@Column(name = "admin", length = 32) public String getAdmin() { return this.admin; }
public void setAdmin(String admin) { this.admin = admin; }
@Column(name = "password", length = 32) public String getPassword() { return this.password; }
public void setPassword(String password) { this.password = password; }
@JSON(serialize = false) @ManyToMany(fetch = FetchType.LAZY) @JoinTable(name = "ux_sys_user_role", joinColumns = { @JoinColumn(name = "adminId") }, inverseJoinColumns = { @JoinColumn(name = "roleId") }) public Set<UxRole> getRoles() { return roles; }
public void setRoles(Set<UxRole> roles) { this.roles = roles; }
} |
说明1:不要理睬getRoles()的@JSON(serialize = false)注解,这个和JPA无关
说明2:@ManyToMany(fetch = FetchType.LAZY)注解,说明UxAdmin与UxRole是多对多的关系,采用的是默认的懒加载机制,而且从UxRole来看,是双向的多对多关联。所以必须采用专门的维护关系表来维护多对多关联关系。
说明3:@JoinTable(……)注解,利用表名为ux_sys_user_role作为关系维护表。UxAdmin实体表用字段adminId作为ux_sys_user_role的外键,用于维护UxAdmin实体。roleId是维护另一个实体——UxRole的roleId字段。之所以用Set作为集合关联,是因为需求不能让用户的角色重复。inverseJoinColumns是定义指向非所有者主表的外键列。