数据填充(翻译)
Crane4j 简介
Crane4j 一个简单易用的关联字段填充框架,能够通过简单的注解配置快速根据外键/编码值填充相关字段,支持字典,枚举,方法等多种数据源。
场景一:填充用户昵称
每一张业务表基本都会涉及 createUser
、updateUser
等审计字段,每次为了查询创建人信息,就不得不写一套联表 SQL。现在 ContiNew Admin 有了 Crane4j 的加成,你只需要参考如下使用即可。 如果继承了 BaseResp
、BaseDetailResp
,那下方这注解也不用了。
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
字段。
// 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
,那么它提供的那些查询方法都已经配置好了填充触发器,你直接使用或重写内容即可。
// 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);
}
}
场景二:一次性填充
除了高频使用的用户名填充,本项目中还有只需要填充一次的场景,这种只需要一次的场景,个人建议省去第一步。
示例如下:
// 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