级联数据获取方案
-
背景,分布式系统中,我们需要数据级联,很多时候拿到的是userId或者List
,然后返回给前端展示的时候需要id对应的一些其他信息比如昵称。为啥我们只有id,没有直接查询出来这些信息呢?可能是表关联太多,性能低。也可能是对应的数据在另外的服务上面,没法用表关联。 -
首先说一句,通过id 轮询查询 附加信息是被禁用的,效率太低。当然你可以自己通过id批量查询,但是如果一个 返回值里面有多个这样的数据,然后每个类似的接口都要在写一边。略微有点膈应。
-
下面是我建议的统一解决方案。
-
我们定义CascadeData接口,表示这样的对象可以级联查询。
-
我们定义一个CascadeDataLoader接口,来处理CascadeData对象的查询。
-
我们需要有一个配置类存着CascadeData类型和处理这个加载的实现类。比如说是一个Map<CascadeData.class,CascadeDataLoader>这样的配置。CascadeDataLoader加载的方法一定要支持批量。
-
我们可以在返回值方法上用一个自定义注解 @Cascade 表示返回值需要解析级联关系。
-
对象和对象的 成员 构成一个tree,解析级联关系设计一个下探多次层的问题,我们可以在定义一个注解@CascadeDelivery,表示需要向下传递解析关系。
-
然后我们按照CascadeData类型收集需要级联对象类型和参数,放到类似 Map<CascadeData.class,List>这样的数据结构中。
-
然后按照类型执行批量查询,把结果放到需要加载的对象里面去。下面是怎么吧数据放回去方案。
-
我们也可以只要是CascadeData接口的参数都去做批量查询,并且填充,但是这样不够精确,不建议。
-
我们可以优化处理,通过注解 @Padding 描述那些是需要加载的,比如在set方法上面加上指定注解,这样的才收集,并且批量查询完成以后通过set方法设置进去。
-
我们也可以在get方法上做注解 @Resolve 标记,解析的过程中通过 CascadeData 把最终的结果对象预先放到 CascadeData 实现类中 ,批量查询完成以后,让CascadeData里面对应的 get方法通过 类型和参数去获取值。
-
优化,类通常是固定的,那些成员变量应该收集这些可以在第一次解析以后缓存起来,后面通过这种缓存可以节省每次都都去反射解析那些成员变量应该收集过过程。
-
-
上面的方法核心在于id应该批量查询,设计方案参考了valid对参数验证注解定义思路和copy对象,通过set 方法提高效率的思路。
posted on 2023-01-09 00:22 zhangyukun 阅读(161) 评论(0) 编辑 收藏 举报