在项目中,一般会须要对用户的访问权限作一个限制和区分,即经典的 用户--角色--菜单 角色管理架构。在这个架构中,用户和角色的关系基本肯定,即多对一的关系;而角色和菜单以前,其实还增长了“菜单操做”这样的操做权限,例如某个角色拥有的菜单操做权限以下图:
菜单和操做权限是一对多的关系,使用springbootjpa的实体类分别是spring
菜单:json
@Entity @Table(name = "menu", uniqueConstraints = { @UniqueConstraint(name = "idx_menuname", columnNames = { "menuName" }) }) @JsonIgnoreProperties(value = { "hibernateLazyInitializer", "handler" }) public class Menu implements Serializable { private static final long serialVersionUID = -6499256046633708586L; @Id @Column(columnDefinition = "varchar(64) comment '菜单id'") private String menuId; // 菜单ID @Column(nullable = false, columnDefinition = "varchar(255) comment '菜单名称'") private String menuName; // 菜单名称 @OneToMany(mappedBy = "menu", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private List<MenuHandle> menuHandles;//菜单操做权限 }
菜单操做权限:api
@Entity @Table(name = "menu_handle") @JsonIgnoreProperties(value = { "hibernateLazyInitializer", "handler" }) public class MenuHandle implements Serializable { private static final long serialVersionUID = -5909986386327673973L; @Id @Column(columnDefinition = "varchar(64) comment '操做权限id'") private String handleId; // 操做权限id @Column(nullable = false, columnDefinition = "varchar(255) comment '权限名称'") private String name; // 权限名称 @ManyToOne(targetEntity = Menu.class) @JoinColumn(name = "menu_id", updatable = false) private Menu menu;//权限对应菜单 }
角色和菜单是多对多的关系,角色和操做也是多对多的关系springboot
角色:架构
@Entity @Table(name = "role", uniqueConstraints = { @UniqueConstraint(name = "idx_rolename", columnNames = { "roleName" }) }) @JsonIgnoreProperties(value = { "hibernateLazyInitializer", "handler" }) public class Role implements Serializable { private static final long serialVersionUID = -5553646385121286353L; @Id @Column(columnDefinition = "varchar(64) comment '角色id'") private String roleId; @Column(nullable = false, columnDefinition = "varchar(255) comment '角色名称'") private String roleName; @ManyToMany private List<Menu> menus;//角色的菜单 @ManyToMany private List<MenuHandle> roleMenuHandles;//角色的操做权限 }
那么在这个设计中,当我经过springbootjpa api查询某个角色时,角色的menus和roleMenuHandles就会无限循环级联查询,致使查询的对象生成不了正确的json。
我当前的作法是:在权限实体中重写toString方法:app
@Override public String toString() { JSONObject jso = new JSONObject(); jso.put("handleId", handleId); jso.put("name", name); jso.put("menuId", menu.getMenuId()); return jso.toJSONString(); }
若有更好的作法,欢迎补充。ide