全部开发者教程

企业级在线办公系统

我们现在能登陆、退出登陆、修改密码,但是这些跟完整的用户管理模块还差着很多。所以本小节我们来做用户模块CRUD操作中的查询功能,我说的查询指的是有条件分页查询。

图片描述
user.vue页面中有查询用户记录的条件区域,我们可以设置具体的查询条件,如果什么条件都不设置的话,就是无条件分页查找用户记录。

图片描述

一、定义模型层

因为查询条件是动态组合的,所以我们在持久层里面编写SQL语句的时候,要判断某个数据不为空,就把它添加到WHERE子句里面充当查询条件。因为是分页查询,所以我们要在TbUserDao.xml文件中编写两条SQL语句,一个是用来查询总记录数,另一个用来查询分页记录。

因为SQL语句超级复杂,这里我先带着同学们从浅入深逐步拆解这个SQL语句。用户表中role字段是JSON数组格式,用户可以拥有多个角色。

如果我想查询根据角色名称查询用户,那么就要把用户表和角色表做表连接查询。
SELECT u.username 
FROM tb_user u
JOIN tb_role r ON JSON_CONTAINS ( u.role, CONVERT ( r.id, CHAR ) )
WHERE  r.role_name="超级管理员"

如果我现在想要查询用户的部门名称,但是有的员工没有部门,这就需要用左连接来联合部门表,这样可以保证所有的员工都会被查询出来,于是SQL语句进化成了下面的样子。
SELECT u.username,
       d.dept_name AS deptName
FROM tb_user u
JOIN tb_role r ON JSON_CONTAINS ( u.role, CONVERT ( r.id, CHAR ) )
LEFT JOIN tb_dept d ON u.dept_id = d.id
WHERE  r.role_name="超级管理员" 

如果我想要把用户拥有的角色也显示出来,这下就麻烦了。因为一个用户可能拥有多个角色,这怎么能合并成一条用户信息呢。这里我要用`GROUP_CONCAT()`函数把多个角色名称拼接成一个字符串,举例如下:
SELECT GROUP_CONCAT( role_name separator "," )  FROM tb_role;

用上了GROUP_CONCAT()函数,我们的SQL语句变成了下面的样子

SELECT u.username,
       d.dept_name AS deptName,
			 ( 
				SELECT GROUP_CONCAT( role_name separator "," ) 
				FROM tb_role 
				WHERE JSON_CONTAINS ( u.role, CONVERT ( id, CHAR ) ) 
			) AS roles
FROM tb_user u
JOIN tb_role r ON JSON_CONTAINS ( u.role, CONVERT ( r.id, CHAR ) )
LEFT JOIN tb_dept d ON u.dept_id = d.id
WHERE  r.role_name="超级管理员" 

了解过SQL语句的各种语法之后,下面才是我们正式要写的SQL语句。

<select id="searchUserByPage" parameterType="HashMap" resultType="HashMap">
    SELECT
        DISTINCT u.id,
        u.name,
        u.sex,
        u.tel,
        u.email,
        d.dept_name AS dept,
        u.hiredate,
        u.root,
        u.status,
        ( SELECT GROUP_CONCAT( role_name separator "," ) FROM tb_role WHERE JSON_CONTAINS ( u.role, CONVERT ( id, CHAR ) ) ) AS roles
    FROM tb_user u
    JOIN tb_role r ON JSON_CONTAINS ( u.role, CONVERT ( r.id, CHAR ) )
    LEFT JOIN tb_dept d ON u.dept_id = d.id
    WHERE 1=1
    <if test="name!=null">
        AND u.name LIKE "%${name}%"
    </if>
    <if test="sex!=null">
        AND u.sex=#{sex}
    </if>
    <if test="role!=null">
        AND r.role_name=#{role}
    </if>
    <if test="deptId!=null">
        AND d.id=#{deptId}
    </if>
    <if test="status!=null">
        AND u.status=#{status}
    </if>
    LIMIT #{start}, #{length}
</select>
<select id="searchUserCount" parameterType="HashMap" resultType="long">
    SELECT
         COUNT(DISTINCT u.id)
    FROM tb_user u
    JOIN tb_role r ON JSON_CONTAINS ( u.role, CONVERT ( r.id, CHAR ) )
    WHERE 1=1
    <if test="name!=null">
        AND u.name LIKE "%${name}%"
    </if>
    <if test="sex!=null">
        AND u.sex=#{sex}
    </if>
    <if test="role!=null">
        AND r.role_name=#{role}
    </if>
    <if test="deptId!=null">
        AND u.dept_id=#{deptId}
    </if>
    <if test="status!=null">
        AND u.status=#{status}
    </if>
</select>

TbUserDao.java接口中声明两个抽象方法。

public interface TbUserDao {
    ……
    public ArrayList<HashMap> searchUserByPage(HashMap param);
    public long searchUserCount(HashMap param);
}

二、定义业务层

UserService.java接口中声明抽象方法。

public interface UserService {
    ……
    public PageUtils searchUserByPage(HashMap param);
}

UserServiceImpl.java类中实现抽象方法。

public class UserServiceImpl implements UserService {
    ……

    @Override
    public PageUtils searchUserByPage(HashMap param) {
        ArrayList<HashMap> list = userDao.searchUserByPage(param);
        long count = userDao.searchUserCount(param);
        int start = (Integer) param.get("start");
        int length = (Integer) param.get("length");
        PageUtils pageUtils = new PageUtils(list, count, start, length);
        return pageUtils;
    }
}

三、定义Web层

创建SearchUserByPageForm.java类,保存Ajax提交的数据。

@Data
@Schema(description = "查询用户分页记录表单")
public class SearchUserByPageForm {
    @NotNull(message = "page不能为空")
    @Min(value = 1, message = "page不能小于1")
    @Schema(description = "页数")
    private Integer page;

    @NotNull(message = "length不能为空")
    @Range(min = 10, max = 50, message = "length必须在10~50之间")
    @Schema(description = "每页记录数")
    private Integer length;

    @Pattern(regexp = "^[\\u4e00-\\u9fa5]{1,10}$", message = "name内容不正确")
    @Schema(description = "姓名")
    private String name;

    @Pattern(regexp = "^男$|^女$", message = "sex内容不正确")
    @Schema(description = "性别")
    private String sex;

    @Pattern(regexp = "^[a-zA-Z0-9\\u4e00-\\u9fa5]{2,10}$", message = "role内容不正确")
    @Schema(description = "角色")
    private String role;

    @Min(value = 1, message = "dept不能小于1")
    private Integer deptId;

    @Min(value = 1, message = "status不能小于1")
    private Integer status;

}

UserController.java类中定义Web方法。

@RestController
@RequestMapping("/user")
@Tag(name = "UserController", description = "用户Web接口")
public class UserController {
    ……
        
    @PostMapping("/searchUserByPage")
    @Operation(summary = "查询用户分页记录")
    @SaCheckPermission(value = {"ROOT", "USER:SELECT"}, mode = SaMode.OR)
    public R searchUserByPage(@Valid @RequestBody SearchUserByPageForm form) {
        int page = form.getPage();
        int length = form.getLength();
        int start = (page - 1) * length;
        HashMap param = JSONUtil.parse(form).toBean(HashMap.class);
        param.put("start", start);
        PageUtils pageUtils = userService.searchUserByPage(param);
        return R.ok().put("page", pageUtils);
    }
}