easy_trans数据翻译

1. 介绍

easy trans适用于4种场景
  1. 有userId/idCardNo(身份证号码-唯一键场景) 需要 userName,无需联表查询。
  2. 有gender code 0 需要 男。
  3. 枚举指定属性给前端
  4. 反向翻译
亮点
  1. 缓存支持
  2. 跨微服务翻译支持(User和Order 是2个不同微服务,order里面有userId 需要userName)
  3. 国际化支持
  4. 多种ORM框架适配
  5. 多数据源支持
  6. 集合支持(userIds [1,2,3] 翻译为张三,李四,王五)
  7. 反向翻译支持 男->gender 0 张三->user_id 1 陕西分公司 财务部 -> org_id 1

使用步骤

技术经理/架构 需要做的事情

1 、先把maven 引用加上(主starter+根据自己的ORM框架选择扩展包)


 <dependency>
      <groupId>com.fhs-opensource</groupId>
      <artifactId>easy-trans-spring-boot-starter</artifactId>
      <version>2.2.9</version>
  </dependency>

Mybatis plus 扩展:

 <dependency>
     <groupId>com.fhs-opensource</groupId>
     <artifactId>easy-trans-mybatis-plus-extend</artifactId>
     <version>2.2.9</version>
 </dependency>

JPA 扩展:

<dependency>
   <groupId>com.fhs-opensource</groupId>
   <artifactId>easy-trans-jpa-extend</artifactId>
   <version>2.2.9</version>
</dependency>

JPA Springboot3 扩展:

<dependency>
    <groupId>com.fhs-opensource</groupId>
    <artifactId>easy-trans-jpa-sb3-extend</artifactId>
    <version>2.2.3</version>
</dependency>

Beetl SQL 扩展:

 <dependency>
     <groupId>com.fhs-opensource</groupId>
     <artifactId>easy-trans-beetl-sql-extend</artifactId>
     <version>2.2.9</version>
 </dependency>

TK Mybatis(通用mapper) 扩展:

<dependency>
   <groupId>com.fhs-opensource</groupId>
   <artifactId>easy-trans-tk-extend</artifactId>
   <version>2.2.9</version>
</dependency>

mybatis flex 扩展:

<dependency>
   <groupId>com.fhs-opensource</groupId>
   <artifactId>easy-trans-mybatis-flex-extend</artifactId>
   <version>2.2.9</version>
</dependency>

如果使用Redis请添加redis的引用(如果之前加过了请不要重复添加)

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

反向翻译专用扩展,反向翻译的最低版本为:2.2.3-M1,详情见反向翻译章节

<dependency>
    <groupId>com.fhs-opensource</groupId>
    <artifactId>easy-trans-untrans-driver</artifactId>
    <version>2.2.9</version>
</dependency>

2、在yaml中添加如下配置

easy-trans:
   #启用redis缓存 如果不用redis请设置为false
   is-enable-redis: true
   #启用全局翻译(拦截所有responseBody进行自动翻译),如果对于性能要求很高可关闭此配置
   is-enable-global: true 
   #启用平铺模式
   is-enable-tile: true
   #字典缓存放到redis 微服务模式请开启
   dict-use-redis: true 
   # ruoyi相关的请开启
   is-enable-map-result: true
   # 反向翻译数据库类型 mysql
   db-type: mysql 

3、如果不使用redis,请在启动类加禁用掉redis的自动配置类

@SpringBootApplication(exclude = { RedisAutoConfiguration.class })

4、初始化字典数据(如果你们项目没字典表请忽略)

 @Autowired  //注入字典翻译服务
 private  DictionaryTransService dictionaryTransService;
 //在某处将字典缓存刷新到翻译服务中,以下是demo
 Map<String,String> transMap = new HashMap<>();
 transMap.put("0","男");
 transMap.put("1","女");
 dictionaryTransService.refreshCache("gender",transMap);

5、微服务配置
A、白名单添加 /easyTrans/proxy/** 保证其不被拦截,RPC trans的时候easytrans会自动调用目标微服务的接口来获取数据。
B、应用之间的认证可以通过filter/interceptor实现,然后自定义RestTemplate 保证easytrans在请求用户服务的时候带上需要认证的参数
普通程序员需要做的事情

pojo 中添加

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
//实现TransPojo  接口,代表这个类需要被翻译或者被当作翻译的数据源
public class Student implements TransPojo {
     // 字典翻译 ref为非必填
    @Trans(type = TransType.DICTIONARY,key = "sex",ref = "sexName")
    private Integer sex;

    //这个字段可以不写,实现了TransPojo接口后有一个getTransMap方法,sexName可以让前端去transMap取
    private String sexName;
    
    //SIMPLE 翻译,用于关联其他的表进行翻译    schoolName 为 School 的一个字段
    @Trans(type = TransType.SIMPLE,target = School.class,fields = "schoolName")
    private String schoolId;
	
	//远程翻译,调用其他微服务的数据源进行翻译
	@Trans(type = TransType.RPC,targetClassName = "com.fhs.test.pojo.School",fields = "schoolName",serviceName = "easyTrans",alias = "middle")
    private String middleSchoolId;
	
	// 枚举翻译,返回文科还是理科给前端
	@Trans(type=TransType.ENUM,key = "desc")
    private StudentType studentType = StudentType.ARTS;

    public static enum StudentType{

        ARTS("文科"),
        SCIENCES("理科");

        private String desc;
        StudentType(String desc){
            this.desc = desc;
        }
    }
}

然后访问你的controller,看返回结果。

easy trans 支持的五种类型
字典翻译(TransType.DICTIONARY)

需要使用者把字典信息刷新到DictionaryTransService 中进行缓存,使用字典翻译的时候取缓存数据源

简单翻译(TransType.SIMPLE)

比如有userId需要userName或者userPo给前端,原理是组件使用MybatisPlus/JPA的API自动进行查询,把结果放到transMap中。

跨微服务翻译(TransType.RPC)

比如订单和用户是2个微服务,但是我要在订单详情里展示订单的创建人的用户名,需要用到RPC翻译,原理是订单微服务使用restTemplate调用用户服务的一个统一的接口,把需要翻译的id传过去,然后用户微服务使用MybatisPlus/JPA的API自动进行查询把结果给订单微服务,然后订单微服务拿到数据后进行翻译,当然使用者只是需要一个注解,这些事情都是由组件自动完成的。

AutoTrans(TransType.AUTO)

还是id翻译name场景,但是使用者如果想组件调用自己写的方法而不通过Mybatis Plus/JPA 的API进行数据查询,就可以使用AutoTrans
枚举翻译(TransType.ENUM)

比如我要把SEX.BOY 翻译为男,可以用枚举翻译。
项目地址

https://gitee.com/dromara/easy_trans

示例项目

https://gitee.com/fhs-opensource/easy_trans_springboot_demo

2. 基础使用

  1. 配置讲解
easy-trans.is-enable-tile:true 开启平铺模式(transMap的key平铺到和vo一个级别)
easy-trans.is-enable-map-result 开启map自动翻译(ruoyi的ajaxResult 可以使用此配置)
easy-trans.dict-use-redis 字典缓存是否放到redis中 做二级缓存,微服务模式推荐开启
easy-trans.is-enable-global 开启responseBody 全局拦截后自动翻译
easy-trans.is-enable-redis 开启redis支持 微服务模式推荐使用redis
easy-trans.db-type 数据库类型,反向翻译时使用,目前仅支持mysql
  1. 不同的翻译类型
    2.1 类型如何选择

@Trans(type=?) 问号应该怎么写?

字典码翻译 TransType.DICTIONARY
其他表主键/唯一键翻译 TransType.SIMPLE
其他表主键/唯一键翻译 但是 但是 这个表在其他的微服务上 TransType.RPC
自己写代码做翻译的数据源 TransType.AUTO_TRANS

2.2 实战

// 字典翻译 
@Trans(type = TransType.DICTIONARY,key = "sex")
private Integer sex;

//SIMPLE 使用schoolId 获取 schoolName
@Trans(type = TransType.SIMPLE,target = School.class,fields = "schoolName")
private String schoolId;

//RPC 使用其他微服务的school表的id获取 schoolName 并且指定别名 
@Trans(type = TransType.RPC,targetClassName = "com.fhs.test.pojo.School",fields = "schoolName",serviceName = "easyTrans",alias = "middle")
private String middleSchoolId;

@Trans的详细使用请点击左侧@trans注解详解章节
3、自动翻译和手动翻译
easy-trans.is-enable-global 设置为true的时候,所有的responseBody框架都会拦截尝试翻译,支持嵌套。称之为自动翻译。
可以注入 TransService 然后调用 transOne或者transBatch 来翻译一个或者多对象,称之为手动翻译,手动翻译不支持平铺。
使用@TransMethodResult 标记方法,框架会自动翻译方法return的值 基于AOP实现。
开启全局翻译后 如果某个controller的返回值不需要返回结果可以 添加@IgnoreTrans 到方法上

//手动翻译
@Autowired
private TransService transService;
transService.transOne(school);
transService.transBatch(schoolList);

//标记方法结果翻译
@TransMethodResult
public Student getStudent(){
        Student student = new Student();
        student.setTeacherId(1);
        return student;
}

//忽略翻译
@IgnoreTrans
@GetMapping("/one")
public HttpResult<Student> student(){
	 return HttpResult.success(new Student());
}

4、多个翻译

多个翻译指的是字段的value 是多个,比如List,Set,数组,逗号分隔的字符串等等。
字典,RPC,SIMPLE 均支持多个翻译,不需要单独写什么,框架会判断如果value.toString 后带逗号就会走多个翻译的逻辑。
5、忽略翻译
如果是返回tree格式数据的接口,强烈建议手动翻译,然后使用忽略翻译注解忽略此接口的自动翻译,忽略翻译可在controller的方法上标记@IgnoreTrans注解。

3.注解详解

1、type

指定翻译的数据源
easy trans支持多种数据源,所以要手动指定。 可选值:

TransType.AUTO_TRANS 自动自定义数据源翻译,左侧有单独的章节讲解如何自定义数据源。
TransType.DICTIONARY 字典缓存为数据源
TransType.SIMPLE 本微服务/单体项目系统自动查表作为数据源
TransType.RPC 自动调用其他微服务接口进行自动查表作为数据源

2、key

指定具体数据源(type为TransType.AUTO_TRANS或者TransType.DICTIONARY才需要配置)

type为TransType.DICTIONARY 传入字典分组编码 比如orderStatus

3、ref

将翻译出来的数据映射到本pojo的某个属性上
比如根据userId翻译userName,vo中已经有userName了,可以通过ref对vo的username进行赋值。
4、refs

类似ref,不过支持多个,是数组格式 不是字符串逗号分隔哦

----推荐使用平铺模式来代替ref和refs(详情见左侧平铺模式)----
5、target

TransType.SIMPLE的时候指定对方的po类
比如是userId那么就指定UserPo.class
6、targetClassName

TransType.RPC的时候指定对方的po类全名
com.ucenter.po.User
7、fields

用来指定我需要对方类的要哪个字段(TransType.SIMPLE和TransType.RPC可用)
支持指定多个,数组格式,不是字符串分隔哦
8、alias

别名,解决翻译结果字段名重名问题
一个vo有createUserId和updateUserId 他们的结果都叫userName 就可以通过别名来区分,比如updateUserId配置了update 那么结果就为updateUserName。
9、serviceName

微服务名称(TransType.RPC 有效)
TransType.RPC的时候组件自动调用其他微服务的接口获取数据,所以要指定服务名称,easyTrans会自动去注册中心获取对应的服务实例URL进行调用。
10、serviceContextPath

服务的context-path
如果远程微服务配置了context-path 可以通过此属性来配置,保证RPC调用不会404
11、 uniqueField

vo中的属性不是对方的id,而是唯一键,这里配置target类唯一键的字段名。
TransType.RPC 和TransType.SIMPLE 可用。
注意:不支持同一个类中混用id和唯一键,比如:Student类中有createUserId 和 updateUserMobile(用户的唯一键字段)
12、dataSource

数据源名称
在多数据源环境下指定此翻译使用哪个数据源 TransType.SIMPLE 有效。
13、sort
翻译顺序
比如 文章表有createBy 字段 对应用户表 用户表有orgid字段对应 组织表。 文章vo需要展示创建人以及创建人所在部门。 就可以指定sort 先对createBy字段进行翻译,取orgid用ref设置到文章vo上,然后再用orgid翻译org的名称。

4. 缓存

1、缓存开启
1.1 字典缓存

字典默认使用hashmap来存放缓存,我们也支持使用redis 来组二级缓存,这样内存中没有的时候会自动去redis里面找,然后放到内存中,解决了多微服务字典问题,也保证了性能。
开启方式:

easy-trans:
 dict-use-redis : true 

1.2 SIMPLE 翻译缓存

可以使用@TransDefaultSett 来开启SIMPLE的缓存功能,只需要给数据源PO类上加@TransDefaultSett(isUseCache = true) 即可。
可选参数:

isUseCache 是否开启 缓存 默认为false 需要开启设置为true即可
cacheSeconds 缓存失效时间 单位秒 默认5
maxCache 最大缓存数量 默认为1000
isAccess 默认false 设置为true的话会按照最后一次访问时间 进行缓存过期计时 false按照添加时间计时

1.3 RPC 翻译缓存

在配置类上添加:

@Autowired
private TransCacheManager transCacheManager;
transCacheManager.setRpcTransCache("com.fhs.test.pojo.School",
         SimpleTransService.TransCacheSett.builder().cacheSeconds(20).maxCache(1000).build());

TransCacheSett 类同样包含 cacheSeconds、 maxCache、 isAccess 3个参数。 上面这段代码要配置到消费者对应微服务中,比如Order中要翻译userid order和user是2个微服务,要把代码放到order微服务里,而不是user微服务。
SimpleTransService.TransCacheSett 使用build构造的时候默认值不起作用,会导致缓存配置不起作用,所以cacheSeconds和maxCache都要手动指定。
2、缓存刷新/清理
2.1 字典缓存

在微服务模式下,如果修改了某个字典,可以通过以下方式刷新各个微服务字典:


      Map<String,String> transMap = new HashMap<>();
      transMap.put("0","男");
      transMap.put("1","女");
      dictionaryTransService.refreshCacheAndNoticeOtherService("gender",transMap);

当执行了上面的代码后,easy trans会刷新redis的缓存,然后清理掉各个微服务的内存缓存 重新获取redis中的缓存。
2.2 SIMPLE RPC 翻译缓存清理


@Autowired
private TransCacheManager transCacheManager;
transCacheManager.clearCache(User.class,"1");

通过上述代码即可清理掉本微服务和其他微服务的所有跟User相关的SIMPLE和RPC缓存。 PS:如果要清理掉其他微服务的RPC缓存,需要使用Redis。因为我用redis做了广播去清理。
3、uniqueField 使用缓存

注意:暂时不支持uniqueField 和 pkey相同字段 比如 主键有个1 uniqueField 还有一个1 他们代表不同的数据。
通过以下方式来配置User除了主键外 还要根据身份证号码字段进行缓存匹配

transCacheManager.setUniqueFieldCache("com.xx.User","idNo");
  • 26
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

游侠小马哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值