有时候不同的业务需要查询不同的数据,如果都全表查询,效率较低,网络传输量也比较大,所以可以采取自定义需要查询的字段的方式解决。
我们可以通过入参传入需要查询的字段和排序字段进行数据查询,然后返回数据信息
先建表枚举类
public enum TableEnum {
ORDER_INFO("order_info"),
DRIVER_ORDER_INFO("driver_order_info"),
DRIVER_PASSENGER_RELATION("driver_passenger_relation");
TableEnum(String tableName) {
this.tableName = tableName;
}
String tableName;
public String getTableName() {
return tableName;
}
}
表字段接口,面向接口变成,方便方法复用:
public interface BaseTableField {
final static String FIELD_ALL = "_all";
/**
* 字段列表
*/
final static Set<String> fieldSet = new HashSet<>();
/**
* 字段转换map,比如driverPhone可以读取 driverPhoneEncrypt
*/
final static Map<String, String> fieldConvertMap = new HashMap<>();
public String getFieldName();
public TableEnum getTableEnum();
public String getTableName();
}
表字段枚举类
/**
* 订单字段信息 此处为示例,只写两个字段供参考
*/
public enum OrderInfoFieldEnum implements BaseTableField {
/**
* 所有字段,添加all后会返回所有字段信息,不推荐使用,还是使用明确的字段性能好,好排查问题
*/
ALL(FIELD_ALL),
/**
* 订单id
*/
ORDER_ID("order_id"),
/**
* userid
*/
USER_ID("user_id")
;
//获取所有字段信息,填充到map,用来判断字符是否存在
static {
for (OrderInfoFieldEnum item :
OrderInfoFieldEnum.values()) {
fieldSet.add(item.getFieldName());
}
}
OrderInfoFieldEnum(String fieldName) {
this.fieldName = fieldName;
}
String fieldName;
public String getFieldName() {
return fieldName;
}
@Override
public TableEnum getTableEnum() {
return TableEnum.ORDER_INFO;
}
@Override
public String getTableName() {
return TableEnum.ORDER_INFO.tableName;
}
}
排序枚举类
public enum SortEnum {
ASC("asc"),
DESC("desc"),
;
SortEnum(String sort) {
this.sort = sort;
}
String sort;
public String getSort() {
return sort;
}
}
结果过滤类,封装了需要的字段还有排序字段信息。此处用枚举类的主要目的是为了参数的合法化,想简单的话可以直接用字符串。
@Data
public class ResultFilter {
@ApiModelProperty(value = "返回的字段,类型为Map<表名, Set<列明>>,有枚举类可以使用")
Map<TableEnum, Set<String>> returnFieldMap;
@ApiModelProperty(value = "排序字段,类型为Map<表名, Map<String, SortEnum>>,有枚举类可以使用")
Map<TableEnum, Map<String, SortEnum>> sortFieldMap;
}
工具类,用来获取查询的字段还有排序字段信息,个别方法可能没用,可以后续自己扩展
public class ReturnFieldUtil {
private static BaseResponse<String> getSelect(Set<String> set, BaseTableField baseTableField) {
return getSelect(set, baseTableField, null);
}
private static BaseResponse<String> getSelect(Set<String> set, BaseTableField baseTableField, String tableAlias) {
if (StringUtils.isEmpty(tableAlias)) {
tableAlias = "";
} else {
tableAlias = tableAlias + ".";
}
if (set.contains(BaseTableField.FIELD_ALL)) {
return ResponseUtils.success(tableAlias + "*");
}
StringBuilder sb = new StringBuilder();
for (String fieldName :
set) {
if (!baseTableField.fieldSet.contains(fieldName)) {
return ResponseUtils.fail(OrderHtapResultEnum.PARAM_ERROR.getCode(), String.format("表:(%s)的字段:(%s),不存在", baseTableField.getTableName(), fieldName));
}
if (baseTableField.fieldConvertMap.containsKey(fieldName)) {
sb.append(",").append(tableAlias).append(baseTableField.fieldConvertMap.get(fieldName));
} else {
sb.append(",").append(tableAlias).append(fieldName);
}
}
return ResponseUtils.success(sb.substring(1));
}
public static BaseResponse<String> getSort(Map<TableEnum, Map<String, SortEnum>> sortFieldMap, BaseTableField baseTableField) {
return getSort(sortFieldMap, baseTableField, null);
}
public static BaseResponse<String> getSort(Map<TableEnum, Map<String, SortEnum>> sortFieldMap, BaseTableField baseTableField, String tableAlias) {
Map<String, SortEnum> sortMap = sortFieldMap.get(baseTableField.getTableEnum());
if (CollectionUtils.isEmpty(sortMap)) {
return ResponseUtils.success();
}
if (StringUtils.isEmpty(tableAlias)) {
tableAlias = "";
} else {
tableAlias = tableAlias + ".";
}
StringBuilder sb = new StringBuilder();
for (String fieldName :
sortMap.keySet()) {
if (!baseTableField.fieldSet.contains(fieldName)) {
return ResponseUtils.fail(OrderHtapResultEnum.PARAM_ERROR.getCode(), String.format("表:(%s)的字段:(%s),不存在", baseTableField.getTableName(), fieldName));
}
if (sortMap.get(fieldName) == null) {
return ResponseUtils.fail(OrderHtapResultEnum.PARAM_ERROR.getCode(), String.format("表:(%s)的字段:(%s),排序值不能为空", baseTableField.getTableName(), fieldName));
}
if (baseTableField.fieldConvertMap.containsKey(fieldName)) {
sb.append(",").append(tableAlias).append(baseTableField.fieldConvertMap.get(fieldName)).append(" ").append(sortMap.get(fieldName).getSort());
} else {
sb.append(",").append(tableAlias).append(fieldName).append(" ").append(sortMap.get(fieldName).getSort());
}
}
return ResponseUtils.success(sb.substring(1));
}
public static BaseResponse<String> getSelect(Map<TableEnum, Set<String>> returnFieldMap, BaseTableField baseTableField, boolean required, String tableAlias, Set<String> needFieldSet) {
Set<String> returnFieldSet = returnFieldMap.get(baseTableField.getTableEnum());
//获取返回列信息
if (CollectionUtils.isEmpty(returnFieldSet)) {
if (required) {
return ResponseUtils.fail(OrderHtapResultEnum.PARAM_ERROR.getCode(), String.format("返回字段returnFiledMap没有(%s)的字段信息", baseTableField.getTableName()));
} else {
return ResponseUtils.success();
}
}
if (!CollectionUtils.isEmpty(needFieldSet)) {
returnFieldSet.addAll(needFieldSet);
}
//生成返回字段sql
return ReturnFieldUtil.getSelect(returnFieldSet, baseTableField, tableAlias);
}
public static BaseResponse<String> getSelect(Map<TableEnum, Set<String>> returnFieldMap, BaseTableField baseTableField, boolean required, String tableAlias) {
return getSelect(returnFieldMap, baseTableField, required, tableAlias, null);
}
public static BaseResponse<String> getSelect(Map<TableEnum, Set<String>> returnFieldMap, BaseTableField baseTableField, boolean required) {
return getSelect(returnFieldMap, baseTableField, required, null, null);
}
}
请求示例
入参
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
@ApiModel(value = "QueryCoustomOrderInfoByOrderId", description = "根据入参的字段查询订单信息")
public class QueryCoustomOrderInfoByOrderIdReq {
@ApiModelProperty(value = "订单id", required = true)
@NotNull(message = "orderId不能为空")
Long orderId;
@ApiModelProperty(value = "用户id")
Long userId;
@NotNull(message = "返回的字段信息不能为空")
@ApiModelProperty(value = "返回的字段,排序字段信息,有枚举类可以使用")
ResultFilter resultFilter;
}
出参
@ApiModel(value = "OrderInfoResp", description = "订单信息")
@Data
@ToString(callSuper = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class OrderInfoResp {
private Long orderId;
private Long userId;
}
控制层
public BaseResponse<OrderInfoResp> queryCoustomOrderInfoByOrderId(@RequestBody @Valid QueryCoustomOrderInfoByOrderIdReq req){
return orderInfoService.queryCoustomOrderInfoByOrderId(req);
}
服务
@Override
public BaseResponse<OrderInfoResp> queryCoustomOrderInfoByOrderId(QueryCoustomOrderInfoByOrderIdReq req) {
if (CollectionUtils.isEmpty(req.getResultFilter().getReturnFieldMap())) {
return ResponseUtils.fail(OrderHtapResultEnum.PARAM_ERROR.getCode(), "返回字段不能为空");
}
//生成返回字段sql
BaseResponse<String> returnFieldsResponse = ReturnFieldUtil.getSelect(req.getResultFilter().getReturnFieldMap(), OrderInfoFieldEnum.ALL,true);
if (!ResponseUtils.isBodyOk(returnFieldsResponse)) {
return ResponseUtils.fail(returnFieldsResponse.getCode(), returnFieldsResponse.getMessage());
}
String returnFields = returnFieldsResponse.getData();
OrderInfo orderInfo = orderInfoMapper.queryCoustomOrderInfoByOrderId(returnFields, req);
if (orderInfo == null) {
return ResponseUtils.success();
}
OrderInfoResp orderInfoResp = new OrderInfoResp();
BeanUtils.copyProperties(orderInfo, orderInfoResp);
return ResponseUtils.success(orderInfoResp);
}
调用示例
Map<TableEnum, Set<String>> returnFieldMap=new HashMap<>();
Set<String> set=new HashSet<>();
set.add(OrderInfoFieldEnum.ORDER_ID.getFieldName());
set.add(OrderInfoFieldEnum.USER_ID.getFieldName());
returnFieldMap.put(TableEnum.ORDER_INFO,set);
QueryCoustomOrderInfoByOrderIdReq req=new QueryCoustomOrderInfoByOrderIdReq();
req.setOrderId(1L);
ResultFilter returnFieldReq=new ResultFilter();
returnFieldReq.setReturnFieldMap(returnFieldMap);
req.setResultFilter(returnFieldReq);
Map<TableEnum, Map<String, SortEnum>> sortFieldMap=new HashMap<>();
Map<String, SortEnum> sortMap=new HashMap<>();
sortMap.put(OrderInfoFieldEnum.ORDER_ID.getFieldName(),SortEnum.ASC);
sortFieldMap.put(TableEnum.ORDER_INFO,sortMap);
returnFieldReq.setSortFieldMap(sortFieldMap);
try {
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders
.post("/orderhtap/order/queryCoustomOrderInfoByOrderId")
.contentType(MediaType.APPLICATION_JSON)
//传json参数
.content(JSON.toJSONBytes(req))
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print())
.andReturn();
BaseResponse baseResponse = JSON.parseObject(mvcResult.getResponse().getContentAsString(), BaseResponse.class);
Assert.assertEquals(OrderHtapResultEnum.SUCCESS.getCode(), baseResponse.getCode());
} catch (Exception e) {
e.printStackTrace();
}
此示例是个单表查询示例。还可以实现多表关联查询示例。
多表查询示例
入参
public class QueryDriverCompleteOrder2Req {
/**
* 司机Id.
*/
@ApiModelProperty(value = "司机Id.", required = true)
@NotNull(message = "司机Id不能为空")
private Long driverId;
/**
* 状态.
*/
@ApiModelProperty(value = "状态.", required = true)
@NotNull(message = "状态不能为空")
private List<Integer> statusList;
/**
* 结束时间开始时间.
*/
@ApiModelProperty(value = "结束时间开始时间", required = true)
@NotNull(message = "结束时间开始时间不能为空")
private Long timeEndStart;
/**
* 结束时间结束时间.
*/
@ApiModelProperty(value = "结束时间结束时间", required = true)
@NotNull(message = "结束时间结束时间不能为空")
private Long timeEndEnd;
@NotNull(message = "返回的字段信息不能为空")
@ApiModelProperty(value = "返回的字段,排序字段信息,有枚举类可以使用")
ResultFilter resultFilter;
}
出参
public class QueryDriverCompleteOrder2Resp extends DriverOrderInfoDto {
DriverPassengerRelationDto driverPassengerRelation;
}
控制层
@ApiOperation(value = "查询一定时间内司机完单数量", notes = "查询一定时间内司机完单数量", httpMethod = "POST")
@PostMapping(value = "/queryDriverCompleteOrder2")
public BaseResponse<List<QueryDriverCompleteOrder2Resp>> queryDriverCompleteOrder2(@RequestBody @Valid QueryDriverCompleteOrder2Req req) {
return driverOrderInfoService.queryDriverCompleteOrder2(req);
}
服务层
@Override
public BaseResponse<List<QueryDriverCompleteOrder2Resp>> queryDriverCompleteOrder2(QueryDriverCompleteOrder2Req req) {
if (CollectionUtils.isEmpty(req.getResultFilter().getReturnFieldMap())) {
return ResponseUtils.fail(OrderHtapResultEnum.PARAM_ERROR.getCode(), "返回字段不能为空");
}
//获取driverOrderInfo返回列信息
BaseResponse<String> returnFieldsResponseDriverOrderInfo = ReturnFieldUtil.getSelect(req.getResultFilter().getReturnFieldMap(), DriverOrderInfoFieldEnum.ALL, true, "doi", Sets.newHashSet(DriverOrderInfoFieldEnum.ORDER_ID.getFieldName()));
if (!ResponseUtils.isBodyOk(returnFieldsResponseDriverOrderInfo)) {
return ResponseUtils.fail(returnFieldsResponseDriverOrderInfo.getCode(), returnFieldsResponseDriverOrderInfo.getMessage());
}
String returnFieldsDriverOrderInfo = returnFieldsResponseDriverOrderInfo.getData();
//获取driverPassengerRelation返回列信息
BaseResponse<String> returnFieldsResponseDriverPassengerRelation = ReturnFieldUtil.getSelect(req.getResultFilter().getReturnFieldMap(), DriverPassengerRelationFieldEnum.ALL, false, null, Sets.newHashSet(DriverPassengerRelationFieldEnum.ORDER_ID.getFieldName()));
if (!ResponseUtils.isBodyOk(returnFieldsResponseDriverPassengerRelation)) {
return ResponseUtils.fail(returnFieldsResponseDriverPassengerRelation.getCode(), returnFieldsResponseDriverPassengerRelation.getMessage());
}
String returnFieldsDriverPassengerRelation = returnFieldsResponseDriverPassengerRelation.getData();
//获取排序字段信息
BaseResponse<String> sortResponse = getQueryDriverCompleteOrder2Sort(req.getResultFilter().getSortFieldMap());
if (!ResponseUtils.isBodyOk(sortResponse)) {
return ResponseUtils.fail(sortResponse.getCode(), sortResponse.getMessage());
}
String sort = sortResponse.getData();
List<DriverOrderInfo> driverOrderInfoList = driverOrderInfoMapper.queryDriverCompleteOrder2(req, returnFieldsDriverOrderInfo, sort);
if (CollectionUtils.isEmpty(driverOrderInfoList)) {
return ResponseUtils.success();
}
List<QueryDriverCompleteOrder2Resp> queryDriverCompleteOrder2RespList = new ArrayList<>(driverOrderInfoList.size());
List<Long> orderIdList = new ArrayList<>(driverOrderInfoList.size());
Map<Long, QueryDriverCompleteOrder2Resp> queryDriverCompleteOrder2RespMap = new HashMap<>(driverOrderInfoList.size());
for (DriverOrderInfo driverOrderInfo :
driverOrderInfoList) {
QueryDriverCompleteOrder2Resp queryDriverCompleteOrder2Resp = new QueryDriverCompleteOrder2Resp();
BeanUtils.copyProperties(driverOrderInfo, queryDriverCompleteOrder2Resp);
queryDriverCompleteOrder2RespList.add(queryDriverCompleteOrder2Resp);
queryDriverCompleteOrder2RespMap.put(queryDriverCompleteOrder2Resp.getOrderId(), queryDriverCompleteOrder2Resp);
orderIdList.add(queryDriverCompleteOrder2Resp.getOrderId());
}
if (StringUtils.isEmpty(returnFieldsDriverPassengerRelation)) {
return ResponseUtils.success(queryDriverCompleteOrder2RespList);
}
List<DriverPassengerRelation> driverPassengerRelationList = driverPassengerRelationMapper.queryDriverCompleteOrderRelation2(orderIdList, req.getDriverId(), returnFieldsDriverPassengerRelation);
for (DriverPassengerRelation driverPassengerRelation :
driverPassengerRelationList) {
DriverPassengerRelationDto driverPassengerRelationDto = new DriverPassengerRelationDto();
BeanUtils.copyProperties(driverPassengerRelation, driverPassengerRelationDto);
queryDriverCompleteOrder2RespMap.get(driverPassengerRelationDto.getOrderId()).setDriverPassengerRelation(driverPassengerRelationDto);
}
return ResponseUtils.success(queryDriverCompleteOrder2RespList);
}
调用示例
@Test
public void testQueryDriverCompleteOrder2() {
QueryDriverCompleteOrder2Req req = new QueryDriverCompleteOrder2Req();
req.setDriverId(7001552L);
req.setTimeEndStart(1676454895L);
req.setTimeEndEnd(1676454895L);
req.setStatusList(Lists.newArrayList(9,8));
ResultFilter returnFieldReq=new ResultFilter();
Map<TableEnum,Set<String>>returnFieldMap=new HashMap<>();
Set<String> setDriverOrderInfo=new HashSet<>();
setDriverOrderInfo.add(DriverOrderInfoFieldEnum.ORDER_ID.getFieldName());
setDriverOrderInfo.add(DriverOrderInfoFieldEnum.DRIVER_PHONE_ENCRYPT.getFieldName());
setDriverOrderInfo.add(DriverOrderInfoFieldEnum.DRIVER_PHONE.getFieldName());
returnFieldMap.put(TableEnum.DRIVER_ORDER_INFO,setDriverOrderInfo);
Set<String> setDriverPassengerRelation=new HashSet<>();
setDriverPassengerRelation.add(DriverPassengerRelationFieldEnum.TIME_END.getFieldName());
setDriverPassengerRelation.add(DriverPassengerRelationFieldEnum.ORDER_ID.getFieldName());
setDriverPassengerRelation.add(DriverPassengerRelationFieldEnum.PASSENGER_ORDER_ID.getFieldName());
setDriverPassengerRelation.add(DriverPassengerRelationFieldEnum.DRIVER_ID.getFieldName());
setDriverPassengerRelation.add(DriverPassengerRelationFieldEnum.CHARGE_DRIVER_DISCOUNTED_BASIC_AMOUNT.getFieldName());
returnFieldMap.put(TableEnum.DRIVER_PASSENGER_RELATION,setDriverPassengerRelation);
returnFieldReq.setReturnFieldMap(returnFieldMap);
Map<TableEnum, Map<String, SortEnum>> sortFieldMap=new HashMap<>();
Map<String, SortEnum> sortMap=new HashMap<>();
sortMap.put(DriverPassengerRelationFieldEnum.TIME_END.getFieldName(),SortEnum.ASC);
sortFieldMap.put(TableEnum.DRIVER_PASSENGER_RELATION,sortMap);
returnFieldReq.setSortFieldMap(sortFieldMap);
req.setResultFilter(returnFieldReq);
try {
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders
.post("/orderhtap/driverorder/queryDriverCompleteOrder2")
.contentType(MediaType.APPLICATION_JSON)
//传json参数
.content(JSON.toJSONBytes(req))
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print())
.andReturn();
BaseResponse baseResponse=JSON.parseObject(mvcResult.getResponse().getContentAsString(),BaseResponse.class);
Assert.assertEquals(OrderHtapResultEnum.SUCCESS.getCode(),baseResponse.getCode());
} catch (Exception e) {
e.printStackTrace();
}
}