關於權限管理系統的設計問題和思考,以及其springbootjpa的實現方法

在項目中,一般會須要對用戶的訪問權限作一個限制和區分,即經典的 用戶--角色--菜單 角色管理架構。在這個架構中,用戶和角色的關係基本肯定,即多對一的關係;而角色和菜單以前,其實還增長了「菜單操做」這樣的操做權限,例如某個角色擁有的菜單操做權限以下圖:
image.png
菜單和操做權限是一對多的關係,使用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

相關文章
相關標籤/搜索