You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Spring CriteriaBuilder实现列值掩码返回自定义默认值

实现基于权限的JPA列值掩码(CriteriaBuilder方式)

核心思路

根据用户权限判断是否需要对指定列进行掩码处理,通过Specification结合CriteriaBuilder构造查询逻辑,将目标列的原始值替换为固定默认值,而非直接查询数据库中的原始数据。

具体实现步骤

1. 定义实体类

对应CODE_TABLE表的实体类示例:

@Entity
@Table(name = "CODE_TABLE")
public class CodeTable {
    @Id
    private Long id;
    private String code;
    // 其他字段、getter/setter方法省略
}

2. 自定义Repository接口

继承JpaRepository和JpaSpecificationExecutor,支持自定义查询条件:

public interface CodeTableRepository extends JpaRepository<CodeTable, Long>, JpaSpecificationExecutor<CodeTable> {
}

3. 构建带权限判断的Specification

实现Specification接口,在逻辑中通过CriteriaBuilder处理列掩码:

import org.springframework.data.jpa.domain.Specification;
import org.springframework.security.core.context.SecurityContextHolder;
import javax.persistence.criteria.*;

public class CodeTableSpecification implements Specification<CodeTable> {
    @Override
    public Predicate toPredicate(Root<CodeTable> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
        // 判断当前用户是否需要触发掩码权限
        boolean needMaskCode = SecurityContextHolder.getContext().getAuthentication()
                .getAuthorities().stream()
                .anyMatch(auth -> auth.getAuthority().equals("ROLE_MASK_CODE"));

        // 构造查询返回字段
        if (needMaskCode) {
            // 将code列替换为固定值'DEFAULT'
            query.multiselect(
                    root.get("id"),
                    criteriaBuilder.literal("DEFAULT").alias("code")
            );
        } else {
            // 正常返回原始字段值
            query.multiselect(root.get("id"), root.get("code"));
        }

        return criteriaBuilder.conjunction(); // 无额外过滤条件,返回空谓词
    }
}

4. 在Controller中调用查询

注入Repository并使用自定义Specification执行查询:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;

@RestController
public class CodeTableController {
    private final CodeTableRepository codeTableRepository;

    public CodeTableController(CodeTableRepository codeTableRepository) {
        this.codeTableRepository = codeTableRepository;
    }

    @GetMapping("/code-tables")
    public List<?> getCodeTables() {
        return codeTableRepository.findAll(new CodeTableSpecification());
    }
}

关键细节说明

  • 权限校验:通过SecurityContextHolder获取当前登录用户的权限集合,判断是否需要启用掩码逻辑。
  • 投影字段控制:使用query.multiselect()精确指定返回字段,确保掩码后的字段别名与实体类属性名一致,避免返回结果的字段映射错误。
  • 扩展性:如果需要对多列进行掩码处理,只需在multiselect中添加对应的criteriaBuilder.literal()语句即可。

内容的提问来源于stack exchange,提问作者hunszab

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 05:12:05