用戶,角色,資源,聯(lián)合查詢(使用注解SQL)

這個(gè)地方就是血淚,我一定要記錄一下。

首先我們的表,有五張表。

用戶表,角色表,資源表,用戶-角色表,角色-資源表。
看一下表結(jié)構(gòu)
用戶表:


g_user.png

角色表:


g_role.png

用戶-角色表:
g_user_role.png

資源表:
image.png

角色-資源表:


image.png

我們信息的層級(jí)關(guān)系是這樣的。用戶分配角色,角色分配資源
現(xiàn)在我們想要獲取用戶zhangSan的所有信息,我們需要聯(lián)合查詢的sql語(yǔ)句是:


聯(lián)合查表.png

然后獲得zhangSan的信息+角色信息+資源信息。

然后主要來看一下我們的代碼結(jié)構(gòu)
用戶信息返回Vo:UserInfoVo

@Getter
@Setter
@NoArgsConstructor
@EqualsAndHashCode
@ToString
public class UserInfoVo implements Serializable {
    private String userName;
    private String userNum;
    @JsonIgnore
    private String password;
    private String phone;
    private String email;
    private String nickName;
    private String lock;
    private List<RoleVo> roles;
}

角色信息返回Vo:

@Getter
@Setter
@NoArgsConstructor
@EqualsAndHashCode
@ToString
public class RoleVo implements Serializable {
    private String roleName;
    private List<ResourceVo> resources;
}

資源返回Vo:

@Getter
@Setter
@NoArgsConstructor
@EqualsAndHashCode
@ToString
public class ResourceVo implements Serializable {
    private String resourceName;
}

接著就是最重要的,mapper文件的調(diào)用。
首先是根據(jù)角色id獲取資源信息

public interface ResourceMapper {
    /**
     * 根據(jù)角色id獲取資源信息
     * @param roleId
     * @return
     */
    @SelectProvider(type = ResourceDynaSqlProvider.class,method = "selectByRoleId")
    ResourceVo selectByRoleId(String roleId);
}

對(duì)應(yīng)的sql文件

public class ResourceDynaSqlProvider {
    /**
     * 通過角色id查找資源表信息
     * @param roleId
     * @return
     */
    public String selectByRoleId(String roleId){
        SQL selectByRoleId = new SQL()
                .SELECT("gre.*")
                .FROM("g_resource gre,g_res_role grr")
                .WHERE("grr.role_id=#{roleId}")
                .AND()
                .WHERE("grr.res_id =gre.id");
        return selectByRoleId.toString();
    }
}

然后根據(jù)角色id獲取角色信息

public interface RoleMapper {

    /**
     * 根據(jù)id獲取角色與資源
     * @param id
     * @return
     */
    @SelectProvider(type = RoleDynaSqlProvider.class,method = "selectById")
    @Results(id = "roleMap", value = {
            @Result(property = "resources",column = "id",javaType = List.class,many = @Many(select = "com.hekiraku.gemini.mapper.ResourceMapper.selectByRoleId"))
    })
    RoleVo selectById(String id);
}

對(duì)應(yīng)的sql

public class RoleDynaSqlProvider {
    /**
     * 根據(jù)id查找角色表信息
     * @param id
     * @return
     */
    public String selectById(String id){
        SQL selectById = new SQL()
                .SELECT("*")
                .FROM("g_role")
                .WHERE("id=#{id}");
        return selectById.toString();
    }
}

根據(jù)用戶id或用戶名獲取用戶信息

public interface UserMapper {

//    @SelectProvider(type=UserDynaSqlProvider.class,method = "selectAllByUserName")
//    UserInfoVo selectAllByUserName(String userName);

    @SelectProvider(type=UserDynaSqlProvider.class,method = "selectById")
    @Results(id = "userMap",value = {
            @Result(property = "roles",column = "id",javaType = List.class,many = @Many(select = "com.hekiraku.gemini.mapper.RoleMapper.selectById"))
    })
    UserInfoVo selectById(String id);
    @SelectProvider(type=UserDynaSqlProvider.class,method = "selectByUserName")
    @ResultMap("userMap")
    UserInfoVo selectByUserName(String userName);
}

對(duì)應(yīng)的sql

public class UserDynaSqlProvider {
    /**
     * 通過id查詢user表信息
     */
    public String selectById(String id){
        SQL selectById = new SQL()
                .SELECT("*")
                .FROM("g_user")
                .WHERE("id=#{id}");
        return selectById.toString();
    }
    /**
     * 通過username查詢user表
     * @param userName
     * @return
     */
    public String selectByUserName(String userName){
        SQL selectIdByUserName = new SQL()
                .SELECT("id")
                .FROM("g_user")
                .WHERE("user_name=#{userName}");
        SQL selectAllById = new SQL()
                .SELECT("*")
                .FROM("g_user")
                .WHERE("id=("+selectIdByUserName.getSelf()+")");
        return selectAllById.toString();
    }
 
}

就這樣,不需要寫多重聯(lián)合查詢的sql,就可以辦到多表數(shù)據(jù)組合了
調(diào)用一下。
好了,這就是我們需求的模樣。


調(diào)用結(jié)果,層級(jí)結(jié)構(gòu).png

但是或許會(huì)覺得這樣子的結(jié)構(gòu)不好使用,那樣我們只需要修改一發(fā)vo的返回。
吧UserInfoVo改成如下:

@Getter
@Setter
@NoArgsConstructor
@EqualsAndHashCode
@ToString
@ApiModel(value = "UserInfoVo",description = "用戶返回信息")
public class UserInfoVo implements Serializable {
    @ApiModelProperty(notes = "用戶名",example = "zhangSan")
    private String userName;
    @ApiModelProperty(notes = "用戶編號(hào)",example = "201904031010001")
    private String userNum;
    @JsonIgnore
    @ApiModelProperty(notes = "密碼",example = "123",hidden = true)
    private String password;
    @ApiModelProperty(notes = "手機(jī)號(hào)",example = "1322232313")
    private String phone;
    @ApiModelProperty(notes = "郵箱地址", example = "gemini@163.com")
    private String email;
    @ApiModelProperty(notes = "昵稱",example = "碧落君(不)")
    private String nickName;
    @ApiModelProperty(notes = "是否凍結(jié)(0正常;1凍結(jié))",example = "0")
    private String lock;
    @JsonIgnore
    private List<RoleVo> roles;
    @ApiModelProperty(name = "setRoles",notes = "角色信息",dataType = "Set<String>")
    public Set<String> getSetRoles(){
        Set<String> setRoles = new HashSet<>();
        if(roles.isEmpty()||roles==null){
            return setRoles;
        }
        Iterator<RoleVo> listRoles = roles.iterator();
        while(listRoles.hasNext()){
            RoleVo roleVo = listRoles.next();
            setRoles.add(roleVo.getRoleName());
        }
        return setRoles;
    }
    @ApiModelProperty(name = "SetResources",notes = "資源信息",dataType = "Set<String>")
    public Set<String> getSetResources(){
        Set<String> setResources = new HashSet<>();
        if(roles.isEmpty()||roles==null){
            return setResources;
        }
        Iterator<RoleVo> listRoles = roles.iterator();
        while(listRoles.hasNext()){
            RoleVo roleVo = listRoles.next();
            setResources.addAll(roleVo.getSetResources());
        }
        return setResources;
    }
}

同時(shí)要記得去掉RoleVo 中的返回list

@Getter
@Setter
@NoArgsConstructor
@EqualsAndHashCode
@ToString
public class RoleVo implements Serializable {
    private String roleName;
    @JsonIgnore
    private List<ResourceVo> resources;
}

然后調(diào)用之后,返回變成


平級(jí)結(jié)構(gòu).png

這種結(jié)構(gòu)更加方便直接獲取信息。

以上。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容