在 动态 SQL(如 MyBatis 的 <if>/<choose>/<foreach> 等) 中进行权限控制,核心思路是:在 SQL 生成阶段就根据当前用户权限决定可见的数据范围或可见字段,而不是在业务代码里“先查再过滤”。
下面按常见场景和方法系统说明。
思路:根据用户角色/部门/权限,动态拼接 WHERE 条件。
<select id="listUser" resultType="User">
SELECT * FROM sys_user
WHERE 1=1
<if test="role == 'ADMIN'">
<!-- 管理员看全部 -->
</if>
<if test="role == 'DEPT_MANAGER'">
AND dept_id = #{deptId}
</if>
<if test="role == 'USER'">
AND create_by = #{userId}
</if>
</select>
✅ 优点:简单直观
❌ 缺点:SQL 分散,权限逻辑易重复
更优雅的方式:
通过 MyBatis 拦截器,在 SQL 执行前自动追加权限条件。
@DataPermissionExecutor.queryAND dept_id IN (...)
if (hasPermission("DEPT")) {
sql += " AND dept_id = " + currentDeptId;
}
✅ 优点:
✅ 常用于:
salary<select id="getUser">
SELECT
id,
username,
<if test="showSalary">
salary,
</if>
create_time
FROM user
</select>
或:
<if test="role == 'ADMIN'">
, salary
</if>
✅ 适合字段少、规则简单的场景
if (!hasPermission("SALARY")) {
user.setSalary(null);
}
✅ 适合:
<choose>
<when test="permission.contains('EXPORT_ALL')">
AND status != 'DELETED'
</when>
<otherwise>
AND status = 'NORMAL'
</otherwise>
</choose>
<if test="tenantId != null">
AND tenant_id = #{tenantId}
</if>
或使用拦截器统一追加。
| 场景 | 推荐方式 |
|---|---|
| 行级权限 | 拦截器 / 动态 WHERE |
| 部门数据隔离 | 拦截器 |
| 字段权限 | 动态 SQL / 后处理 |
| 多租户 | 租户拦截器 |
| 简单系统 | <if> 判断 |
AND (dept_id = 1 OR 1=1)
如果你愿意,我可以:
你现在的权限控制是 角色 / 部门 / 字段 / 多租户 哪种?
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。