业务数据-自动翻译工具

前言

当你做业务内容开发时,数据库数据转化为人类数据,例如:机构id=》机构名称,用户Id=>用户名称。你是否受够了,不同业务的相同转化要写多次,写的抓狂。下面可以看看,我自己写的自动翻译工具,是否符合你的要求。

什么是自动翻译工具

自动翻译工具就是用来解决上述痛点,同时实现一次定义多处使用。通过AOP思想对接口进行拦截,自动触发数据转换和数据组装。只需要定义好翻译者,添加一些注解,剩下的就可以交给自动翻译工具了,电梯:使用场景-简单翻译。

主要思想

自动翻译工具,就是利用Spring AOP思想,对接口进行拦截,针对指定的对象,自动获取数据库数据,再主动调用用户定义的翻译者,获取人类数据,最后在自动填充。

代码结构

在这里插入图片描述
说明:

  1. 用户自定义各种Translator,然后系统自动加载到TranslatorFactory,通过TranslateFactory提供翻译者。
  2. TranslateAspect是核心内容,通过自定义切面,拦截所有@TransAnnotation的方法。

使用场景

简单翻译

简单翻译:根据Dto中的id直接翻译成名字。

  1. 定义翻译者,指定能解决的翻译格式。
/**
 * @author jiakunfeng
 * 根据用户id,返回相对应的用户名称
 */
@Component
public class UserTranslator implements Translator<Long,String> {
    
    
    @Override
    public String name() {
    
    
        return "userTranslator";
    }

    @Override
    public Map<Long, String> translate(List<Long> idList) {
    
    
        //模拟查询数据库获取数据
        return findUserName(idList);
    }

    private Map<Long,String> findUserName(List<Long> idList){
    
    
        Map<Long,String> userNameMap = new HashMap<>();
        for (Long id : idList) {
    
    
            userNameMap.put(id,"酷我音乐盒"+id);
        }
        return userNameMap;
    }
}
  1. 定义被翻译对象,添加@TransObject、@TransSource、@TransTarget
@Data
@NoArgsConstructor
@AllArgsConstructor
/**声明被翻译对象
这是简单根据id翻译名称。
*/
@TransObject
public class KuWoUser implements Serializable {
    
    
    /**声明被翻译对象的id来源*/
    @TransSource(name="userTranslator")
    private Long id;
    /**声明被翻译对象的翻译结果填充*/
    @TransTarget(name="userTranslator")
    private String name;

}.	
  1. 方法调用,添加TransAnnotation
@Service
@Slf4j
public class KuWoUserReadServiceImpl implements KuWoUserReadService{
    
    

    @Override
    @TransAnnotation(translators = {
    
    "userTranslator"})
    public List<KuWoUser> list() {
    
    
        return null;
    }

    @Override
    @TransAnnotation(translators = {
    
    "userTranslator"})
    public KuWoUser findById() {
    
    
        return null;
    }
}

说明:

  1. 自定义Translator时,name至关重要,必须保证不重复,重复会有异常提示,同时后续使用该翻译者的所有注解(@TransSource,@TransTarget)都必须相同。

批次翻译

批次翻译:Dto中用多个相同的变量,但是用的都是一个翻译器。例如:User中的创建人和更新人的名字。只需要修改步骤1。

/**Music对象中的创建人名字和更新人名字都是查询User库就可以翻译,这种现象就是批量翻译,即一个Dto存在多个字段需要用同一个翻译者进行翻译,因此通过group进行区分,请注意group的唯一性(同一个translator必须唯一)*/
@Data
@TransObject
public class Music implements Serializable {
    
    
    private Long id;
    @TransSource(name = "userTranslator",group = "creator")
    private Long creatorId;
    @TransTarget(name = "userTranslator",group = "creator")
    private String creatorName;
    @TransSource(name = "userTranslator",group = "operator")
    private Long operatorId;
    @TransTarget(name = "userTranslator",group = "operator")
    private String operatorName;

    public Music(Long id,Long creatorId,Long operatorId){
    
    
        this.id = id;
        this.creatorId = creatorId;
        this.operatorId = operatorId;
    }
}

剩余的步骤跟简单调用相同。主要是Dto的注解需要特殊处理。

继承翻译

父类声明了相关的翻译,那么子类继承后,不需要再次声明。

@Data
@TransObject
public class BaseUser implements Serializable {
    
    
    @TransSource(name="userTranslator")
    private Long id;
    @TransTarget(name="userTranslator")
    private String name;

    public BaseUser(Long id){
    
    
        this.id = id;
    }
}

@Data
public class QQUser extends BaseUser {
    
    

    public QQUser(Long id) {
    
    
        super(id);
    }
}

QQUser不需要相关的声明,使用的时候按照上述补步骤即可。

多内容翻译

Dto中存在多个需要翻译的字段,例如:存在机构名称、操作人名称需要翻译。只需要修改第2、3步骤即可。

  1. 不同字段添加不同的翻译者
@Data
@NoArgsConstructor
@AllArgsConstructor
/**声明被翻译对象*/
@TransObject
public class KuWoUser implements Serializable {
    
    
    /**声明被翻译对象的id来源*/
    @TransSource(name="userTranslator")
    private Long id;
    /**声明被翻译对象的翻译结果填充*/
    @TransTarget(name="userTranslator")
    private String name;

    @TransSource(name="orgTranslator")
    private Long orgId;
    @TransTarget(name="orgTranslator")
    private String orgName;

}
  1. 修改方法调用中翻译者,添加多个翻译者。
	@Override
    @TransAnnotation(translators = {
    
    "userTranslator","orgTranslator"})
    public List<KuWoUser> listByName() {
    
    
        KuWoUser user1 = new KuWoUser(1L,1111L);
        KuWoUser user2 = new KuWoUser(2L,2222L);
        return Lists.newArrayList(user1,user2);
    }

自定义返回格式翻译

自定义格式翻译:现在的返回值格式,只支持:List、Map(Key)、Map(Value)、Set、Array、单一Object(直接有@TransObject注解),如果想添加更多格式,例如:Response(包装返回值)、Paging(分页)等。只需要添加格式转化者和修改步骤3。

添加转换者

/**
 * 接口的返回值是Paging包装,进行拆包转List
 */
@Component
public class PagingReturnConverter extends AbstractReturnConverter {
    
    
    @Override
    public String name() {
    
    
        return "paging";
    }

    @Override
    public List<Object> covertReturn(Object ret) {
    
    
        Paging<Object> retPage = (Paging<Object>) ret;
        if (retPage.empty()) {
    
    
            return Lists.newArrayList();
        }
        return retPage.getData();
    }
}

添加retType

修改接口调用,@TransAnnotation的retType=“paging”

	@Override
    @TransAnnotation(translators = {
    
    "userTranslator"},retType = "paging")
    public Paging<KuGoUser> paging() {
    
    
        KuGoUser user1 = new KuGoUser(1L, 30,"浙江");
        KuGoUser user2 = new KuGoUser(2L, 31,"杭州");
        return new Paging<>(Lists.newArrayList(user1,user2),2L);
    }

注意事项

  1. AOP拦截的方法的返回值中的集合元素的Class文件必须相同,例如List的所有元素都是同一个Class,严禁:List:List.add(String),List.add(Integer)这种形式的集合。
  2. @TransAnnoation(translators={“XXX”})、@TransTarget(name=“XXX”)、@TransSource(name=“XXX”)、Translator的name()的字符串必须相同。

代码

代码还没有整理完成,后续会放在git上,尽情关注。

说明

后续会补充自动翻译工具的由来和Spring AOP的相关内容。

猜你喜欢

转载自blog.csdn.net/u010652576/article/details/114269990