java mysql自定义查询需要的列

有时候不同的业务需要查询不同的数据,如果都全表查询,效率较低,网络传输量也比较大,所以可以采取自定义需要查询的字段的方式解决。

我们可以通过入参传入需要查询的字段和排序字段进行数据查询,然后返回数据信息

先建表枚举类

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();
        }
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值