Skip to content

远程映射

作者:唐亚峰 | battcn
字数统计:376 字

解决跨服务字段映射问题

当你不想在自己的业务代码入侵太多的 GET、SET 代码可以采用下面的方式,动态去映射字段结果集

有更好的设计意见和思路欢迎反馈

差异分析

大大提高开发效率,去掉冗余的代码

使用之前

javascript
public class ServiceImpl {

    public List<Resp> list() {
        List<Resp> list = baseMapper.list();
        Map<Long, UserInfoResp> map = feignClient.findByIds(ids);
        for (Item item : list) {
            UserInfoResp info = map.get(item.getId());
            if (info == null) {
                continue;
            }
            item.setName(info.getName());
            item.setAvatar(info.getAvatar());
            // .... 更多的赋值动作
        }
        return list;
    }
}

使用之后

注意

该方式不是万能的,目前只支持批量 KEY 的方式,同时要目标服务提供相应的接口才可以

在需要动态映射的方式中添加 @RemoteResult

在需要动态映射的实体中添加 @Remote (支持单个或多个字段映射)

javascript
public class ServiceImpl {
    
    @Override
    @RemoteResult
    public List<Resp> list() {
        return baseMapper.list();
    }
}

注解讲解

@Remote主要目的就是用来告诉 AOP 需要解析和映射的字段是什么

beanName 添加 非跨服务的 Bean Name 注解的接口类,比如你自己服务某个 XXXServiceImpl

beanClass 添加 @FeignClient 注解的接口类

javascript
public class Resp{

    @Remote(beanClass = UserFeign.class, fields = {
        @Remote.FieldRef(source = "nickName", target = "name"),
        @Remote.FieldRef(source = "avatar", target = "avatar"),
    })
    private Long userId;
    
    private String name;
    
    private String avatar;
}

@FeignClient(name = FeignConstants.FEIGN_NAME, dismiss404 = true)
public interface UserFeign extends LoadService<Long, UserInfoResp> {

    /**
     * 根据 ID 批量查询
     *
     * @param ids 唯一键(可能不是主键ID)
     * @return 查询结果
     */
    @Override
    @PostMapping("/users/batch_ids")
    Map<Long, UserInfoResp> findByIds(@RequestBody Set<Long> ids);
}