Java服务_ck服务弹性接口service层和dao层设计实战2
1.背景
在ck等olap数据服务层,为了抽象化我们创建的接口,扩展接口的可服用性,我们一般会把接口设计成弹性接口。弹性接口的意思就是,传入的维度参数列表是可选的、可变的,传出的指标数据列表也是可选的、可变的。
如下表所描述的一个接口为例来对弹性接口进行理解:
| serviceName | getBrandIndBrandRank |
|---|---|
| demensions | STime_ETime_SecondIndId_[ThirdIndId]_[ShopType]_[TerminalId]_[BrandId]_[PriceRangeId] |
| indicators | BrandId_BrandName_RankRound_DealAmt_DealProNum_PV_UV_DealCustPriceAvg_DealRate_CartUser |
| options | PageNum_RowNum_OrderBy |
| attributes |
首先,维度组合是该接口的入参列表,按照属性我们一般将维度划分为demensions、options。对于弹性接口,就设置了一些可传可不穿的参数,上表中中括号中的demensions维度即为弹性维度,全部options都是弹性维度。通过控制传入的维度参数,就可以通过一个接口实现多维度数据的查询。
指标组合就是该接口返回的出参列表,按照属性我们一般将指标划分为indicators、attributes。弹性接口的指标就全部都是可选的,只需要在入参中执行本次请求需要哪些指标即可。
排序字段和分页字段就是比较典型的options维度。
2.接口文档设计

3.创建dao层param类
dao层的param类实际上就是承接接口入参列表的bean类,一般直接借助fastjson组件将jsonObject对象转化为param类对象。
一个需求的所有弹性接口共用一个param类,那么需要将这些接口所涉及到的维度组合全部放进来即可。
创建param类如下:
1 | public class IndustryRankParam { |
注意添加@JSONField注解设置json字段与param属性的对应关系。
4.创建dao层的mapper接口类
dao层的mapper接口类是mybatis基于spring框架生成dao方法实例的基础,供service层依赖引用。
1 | package com.jd.ad.dao.mapper.sztrade; |
5.创建继承整个微服务抽象类的service方法
我们在service类中,为了优雅和美观,将所有接口抽象到同一个query方法中:
1 |
|
6.创建ReqUtils类与工具方法
1.generateParam()方法将jsonObject转化为parambean类对象:
1 | public static Object generateParam(JSONObject jsonObject, Class<?> clazz) { |
很明显,该方法中最主要的步骤,就是把传入的维度组合dimensions、options放入param类对象中。
2.generateCols()生成查询信息:
1 | public static Set generateCols(JSONObject jsonObject) { |
很明显,该方法最主要的步骤,就是从传入的参数中获取本次请求所需要的指标组合indicators、attributes。
7.写出一个接口查询全量指标的sql
做这一步的目的是为了观察sql,sql中抽象出共性较大的弹性查询字段:
getBrandIndCateSummary
1 | select |
getBrandIndCateTrend
1 | select |
从所有sql中可以抽象出比较常用的指标字段组合,比如商品宽表聚合表指标、类目搜索数据表指标、品牌店铺数表指标、商品成交明细表指标、所有指标等。
8.创建IndustryRankUtil类与工具方法
在上述总结的可以弹性变化的指标字段组合的基础之上,创建对应的查询指标组合Set<String>字段或String字段,根据入参中传入的indicators和attributes指标组合来构建这四个字段,并放入到param类对象中,方便后续以占位符的形式放入sql中:
1 | public class IndustryRankUtil { |
11.创建dao层的mapper.xml配置文件
创建这个文件最重要的就是优雅,实现优雅的根本秘诀就是抽象与复用,大体顺序就是resultMap-select-dbsql-tablesql-wheresql:
1 |
|