• 根据表名动态获取数据


    查询接口

    1. @ApiOperation("通用高级搜索")
    2. @PostMapping("/highSearch")
    3. public ResponseResult highSearch(@RequestBody HighSearchVO highSearchVO) {
    4. return dynamicDataRetrievalService.highSearch(highSearchVO);
    5. }

    Service

    1. @Override
    2. @Transactional
    3. public ResponseResult highSearch(HighSearchVO highSearchVO) {
    4. // 检索
    5. highSearchVO.setPageNo((highSearchVO.getPageNo() - 1) * highSearchVO.getPageSize());
    6. for (HighSearch highSearch : highSearchVO.getHighSearches()) {
    7. if ("datetime".equals(highSearch.getColumnType())) {
    8. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    9. String[] times = highSearch.getSearchValue().split("\\|");
    10. try {
    11. highSearch.setStartDate(sdf.parse(times[0]));
    12. highSearch.setEndDate(sdf.parse(times[1]));
    13. } catch (ParseException e) {
    14. e.printStackTrace();
    15. return ResponseResult.fail("时间格式不正确");
    16. }
    17. }
    18. }
    19. List> maps = dynamicDataRetrievalMapper.highSearch(highSearchVO);

    由于是动态的,不能确定返回的List<>中填写哪个实体类型,所以可以用List>数据结构来接,key是数据库字段名,value是对应的值:

    1. list: [
    2. {
    3. "task_name": "落盘任务test1",
    4. "center_freq": "9600MHz",
    5. "file_location": "/files/2022_05_22_10_38_29_281_I_9600MHz_43803",
    6. "pdw_format_id": 1,
    7. "file_name": "2022_05_22_10_38_29_281_I_9600MHz_43803",
    8. "fileSuffix": [
    9. ".dat",
    10. ".pls"
    11. ],
    12. "target_id": 3,
    13. "file_size": 9.2980568E7,
    14. "gather_time": "2022-05-22T10:38:29.281",
    15. "in_time": "2023-11-15T16:04:37",
    16. "pulse_num": 43803,
    17. "gather_id": 2,
    18. "id": 46,
    19. "system_model_id": 1
    20. },
    21. {
    22. "task_name": "落盘任务test1",
    23. "center_freq": "9600MHz",
    24. "file_location": "/files/2022_05_22_10_38_29_281_I_9600MHz_43803",
    25. "pdw_format_id": 1,
    26. "file_name": "2022_05_22_10_38_29_281_I_9600MHz_43803",
    27. "fileSuffix": [
    28. ".dat",
    29. ".pls"
    30. ],
    31. "target_id": 3,
    32. "file_size": 9.2980568E7,
    33. "gather_time": "2022-05-22T10:38:29.281",
    34. "in_time": "2023-11-15T16:04:37",
    35. "pulse_num": 43803,
    36. "gather_id": 2,
    37. "id": 46,
    38. "system_model_id": 1
    39. }
    40. ]

    HighSearchVO

    1. @ApiModel(description = "高级搜索前端传参")
    2. @Data
    3. public class HighSearchVO {
    4. @ApiModelProperty("表名")
    5. private String tableName;
    6. @ApiModelProperty("搜索字段集合")
    7. private List highSearches;
    8. @ApiModelProperty("排序字段")
    9. private String orderColumn;
    10. @ApiModelProperty("排序控制(asc,desc)")
    11. private String orderControl;
    12. @ApiModelProperty("页数")
    13. private Integer pageSize;
    14. @ApiModelProperty("页码")
    15. private Integer pageNo;
    16. }

     HighSearch 

    1. @ApiModel(description = "HIGH_SEARCH实体对象")
    2. @Data
    3. public class HighSearch {
    4. @ApiModelProperty(value = "字段名")
    5. private String columnName;
    6. @ApiModelProperty(value = "字段搜索值")
    7. private String searchValue;
    8. @ApiModelProperty(value = "字段类型")
    9. private String columnType;
    10. @ApiModelProperty(value = "开始时间(如果根据时间查询)")
    11. private Date startDate;
    12. @ApiModelProperty(value = "结束时间(如果根据时间查询)")
    13. private Date endDate;
    14. }

    动态sql:

    1. <select id="highSearch" resultType="java.util.Map" parameterType="com.lin.entity.vo.HighSearchVO">
    2. select * from ${tableName}
    3. where 1 = 1
    4. <if test="highSearches != null">
    5. <foreach collection="highSearches" item="item" separator="AND" open="AND">
    6. <choose>
    7. <when test="item.columnType == 'bigint'||item.columnType == 'int'||item.columnType == 'double'">
    8. ${item.columnName} = ${item.searchValue}
    9. </when>
    10. <when test="item.columnType == 'varchar'||item.columnType == 'VARCHAR'">
    11. ${item.columnName} like concat(concat('%', #{item.searchValue}), '%')
    12. </when>
    13. <when test="item.columnType == 'datetime'">
    14. ${item.columnName} between #{item.startDate} and #{item.endDate}
    15. </when>
    16. </choose>
    17. </foreach>
    18. </if>
    19. <if test="orderColumn != null and orderColumn != ''">
    20. order by ${orderColumn} ${orderControl}
    21. </if>
    22. limit #{pageNo},#{pageSize}
    23. </select>

     

    请求参数:

    1. {
    2. "tableName": "file_meta_data",
    3. "orderColumn": "id",
    4. "orderControl": "desc",
    5. "pageNo": 1,
    6. "pageSize": 10,
    7. "highSearches": [
    8. {
    9. "columnName": "id",
    10. "searchValue": 21,
    11. "columnType": "bigint"
    12. },
    13. {
    14. "columnName": "name",
    15. "searchValue": "小明",
    16. "columnType": "varchar"
    17. }
    18. ]
    19. }

    动态下载导出数据excel

    使用到阿里的easy-excel

    1. @GetMapping("download")
    2. public void download(HttpServletResponse response) throws IOException {
    3. // 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman
    4. response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
    5. response.setCharacterEncoding("utf-8");
    6. // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
    7. String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\\+", "%20");
    8. response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
    9. EasyExcel.write(response.getOutputStream(), DownloadData.class).sheet("模板").doWrite(data());
    10. }
    11. private List data() {
    12. List list = ListUtils.newArrayList();
    13. for (int i = 0; i < 10; i++) {
    14. DownloadData data = new DownloadData();
    15. data.setString("字符串" + 0);
    16. data.setDate(new Date());
    17. data.setDoubleData(0.56);
    18. list.add(data);
    19. }
    20. return list;
    21. }

    上面那个是定死的下载哪个实体对应的数据,而我们现在要求动态,动态获取数据list已经搞定了,但是数据List>要转为阿里api可以识别的(问题一),以及根据表名获取.class运行时类(问题二)。

    问题二解决:

    1. /**
    2. * 表对象枚举
    3. */
    4. public enum TableObjectEnum {
    5. file_meta_data(FileMetaData.class),
    6. radar_sort_pwd(RadarSortPwd.class),
    7. ;
    8. private Class aClass;
    9. TableObjectEnum(Class aClass) {
    10. this.aClass = aClass;
    11. }
    12. public Class getaClass() {
    13. return aClass;
    14. }
    15. public void setaClass(Class aClass) {
    16. this.aClass = aClass;
    17. }
    18. // 根据表名获取对应的 Class(.class运行时类)
    19. public static Class getClassForTableName(String tableName) throws ClassNotFoundException {
    20. for (TableObjectEnum tableObjectEnum : TableObjectEnum.values()) {
    21. if (tableObjectEnum.name().equalsIgnoreCase(tableName)) {
    22. return tableObjectEnum.getaClass();
    23. }
    24. }
    25. throw new ClassNotFoundException("表名没找到对应的类" + tableName);
    26. }
    27. }

    问题一解决:

    1. /**
    2. * 将数据转化为导出可以支持的数据
    3. *
    4. * @param dataList
    5. */
    6. private List convertData(List> dataList, Class objectType) {
    7. List objectList = new ArrayList<>();
    8. ObjectMapper objectMapper = new ObjectMapper();
    9. objectMapper.registerModule(new JavaTimeModule()); // 注册 Java 8 日期/时间模块
    10. try {
    11. // 遍历 dataList 并将每个 Map 转换为对象,添加到列表中
    12. for (Map data : dataList) {
    13. T object = objectMapper.convertValue(data, objectType);
    14. objectList.add(object);
    15. }
    16. } catch (Exception e) {
    17. e.printStackTrace();
    18. }
    19. return objectList;
    20. }

    完整代码

    1. @Override
    2. public void download(HttpServletResponse response, HighSearchVO highSearchVO) throws UnsupportedEncodingException {
    3. String tableName = highSearchVO.getTableName();
    4. // 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman
    5. response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
    6. response.setCharacterEncoding("utf-8");
    7. // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
    8. String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\\+", "%20");
    9. response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
    10. try {
    11. Class classForTableName = TableObjectEnum.getClassForTableName(tableName);
    12. // 查询数据
    13. List> dataList = getData(highSearchVO);
    14. List list = convertData(dataList, classForTableName);
    15. // 忽略字段
    16. Set excludeColumnFiledNames = new HashSet();
    17. // excludeColumnFiledNames.add("pdwId");
    18. EasyExcel.write(response.getOutputStream(), classForTableName)
    19. .excludeColumnFieldNames(excludeColumnFiledNames)
    20. // .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) // 自动列宽
    21. .sheet("模板").doWrite(list);
    22. } catch (ClassNotFoundException | IOException e) {
    23. e.printStackTrace();
    24. }
    25. }

  • 相关阅读:
    linux之ftp服务-1
    网络安全(黑客)自学
    音频的“隐形保镖”——音频数字水印
    kubernetes code-generator使用
    常见的文件系统格式
    Shiro之多Realm的认证及认证策略-yellowcong
    前端周刊第十一期
    等保2.0对云计算有哪些特定的安全要求?
    从源码上看,RocketMQ 5.0 跟 RocketMQ 4.x相比增加了哪几个模块
    TinyEngine 开源低代码引擎首次直播答疑Q&A合集
  • 原文地址:https://blog.csdn.net/weixin_52938172/article/details/134512767