Skip to content

数据填充(翻译)

Crane4j 简介

Crane4j 一个简单易用的关联字段填充框架,能够通过简单的注解配置快速根据外键/编码值填充相关字段,支持字典,枚举,方法等多种数据源。

场景一:填充用户昵称

每一张业务表基本都会涉及 createUserupdateUser 等审计字段,每次为了查询创建人信息,就不得不写一套联表 SQL。现在 ContiNew Admin 有了 Crane4j 的加成,你只需要参考如下使用即可。 如果继承了 BaseRespBaseDetailResp,那下方这注解也不用了。

1、定义数据源容器

由于用户昵称属于高频使用到的数据源容器,所以在 continew-starter-extension-crud 依赖中已经预定义了一个容器 ContainerPool.USER_NICKNAME

使用前只需要实现此接口,然后实现此方法即可。ContiNew Admin UserServiceImpl 中已经处理好了,所以你不需要做任何处理了。

public interface CommonUserService {

    /**
     * 根据 ID 查询昵称
     *
     * @param id ID
     * @return 昵称
     */
    @ContainerMethod(namespace = ContainerPool.USER_NICKNAME, type = MappingType.ORDER_OF_KEYS)
    String getNicknameById(Long id);
}

2、定义填充规则

针对需要填充的实体字段添加填充规则,下方示例表示如果 createUser 字段值不为空,则通过数据源容器 ContainerConstants.USER_NICKNAME 中根据 createUser 字段值查询数据,并将数据赋值给 createUserString 字段。

java
// continew-admin-system/top.continew.admin.system.model.resp.log
@Data
@Schema(description = "日志详情信息")
public class LogDetailResp implements Serializable {
    // 其他字段略
    /**
     * 创建人
     */
    @JsonIgnore
    @ConditionOnPropertyNotNull
    @Assemble(prop = ":createUserString", container = ContainerConstants.USER_NICKNAME)
    private Long createUser;

    /**
     * 创建人
     */
    @Schema(description = "创建人", example = "张三")
    private String createUserString;
}

3、定义填充触发器

到此环节,Crane4j 已经知道如何填充数据了,最后我们只需要在对应方法上触发填充即可。

如果你继承了 BaseServiceImpl,那么它提供的那些查询方法都已经配置好了填充触发器,你直接使用或重写内容即可。

java
// continew-admin-system/top.continew.admin.system.service.impl
@Service
@RequiredArgsConstructor
public class LogServiceImpl implements LogService {
    // 其他方法略
    @Override
    @AutoOperate(type = LogDetailResp.class)
    public LogDetailResp get(Long id) {
        LogDO logDO = baseMapper.selectById(id);
        CheckUtils.throwIfNotExists(logDO, "LogDO", "ID", id);
        return BeanUtil.copyProperties(logDO, LogDetailResp.class);
    }
}

场景二:一次性填充

除了高频使用的用户名填充,本项目中还有只需要填充一次的场景,这种只需要一次的场景,个人建议省去第一步。

示例如下:

java
// continew-admin-system/top.continew.admin.system.service.impl
@Data
@Schema(description = "部门信息")
public class DeptResp extends BaseDetailResp {
    // 其他字段略
    /**
     * 上级部门 ID
     */
    @Schema(description = "上级部门 ID", example = "2")
    @ConditionOnExpression(value = "#target.parentId != 0")
    @AssembleMethod(props = @Mapping(src = "name", ref = "parentName"), targetType = DeptService.class, method = @ContainerMethod(bindMethod = "get", resultType = DeptResp.class))
    private Long parentId;

    /**
     * 上级部门
     */
    @Schema(description = "上级部门", example = "天津总部")
    private String parentName;
}

然后根据你的需要去配置填充触发即可,ContiNew Admin 项目中,由于 DeptServiceImpl 继承了 BaseServiceImpl,且所需填充场景就是其提供的 tree 方法,所以不需要定义了。

参考资料

1.Crane4j 强大又好用的关联字段填充框架:https://opengoofy.github.io/crane4j