代码经验


代码经验

MyBatisPlus or 和 like 在一个条件里

List<TToxicologicalReport> list = toxicologicalReportService.list(new LambdaQueryWrapper<TToxicologicalReport().eq(TToxicologicalReport::getForm, 0)
                .and(StringUtils.isNotBlank(params), w -> w.like(TToxicologicalReport::getName, params)
                        .or().like(TToxicologicalReport::getYears, params))
                .orderByDesc(TToxicologicalReport::getId).last("limit 10"));
new LambdaQueryWrapper<>().and(StringUtils.isNotBlank(params), w -> w.like(TReport::getNumber, params).or().like(TReport::getCompanyName, params));

其实可以发现,就是把 or 和 like ,放到一个 and 里面。

内部类在 Mapper 层的使用

  • 内部类
/**
 * 数据源 DTO
 */
@Data
public class CalculateDetailVO {

    @ApiModelProperty("主键")
    private Integer id;

    @ApiModelProperty("核算报告表ID")
    private Integer reportId;

    @ApiModelProperty("排放源附件")
    private List<CalculateFileVO> sourceFile = Lists.newArrayList();

    /**
     * 数据源附件 DTO
     */
    @Data
    public static class CalculateFileVO {

        @ApiModelProperty("主键")
        private Integer id;

        @ApiModelProperty("附件文件id")
        private Integer fileId;

        @ApiModelProperty("附件文件名")
        private String fileName;

        @ApiModelProperty("附件文件名地址")
        private String fileUrl;

        @ApiModelProperty("类别(1-核算数据表附件,2-自定义因子附件)")
        private Integer type;
    }
}
  • Mapper 层
List<CalculateDetailVO.CalculateFileVO> getFiles(Integer otherId, Integer type);
<select id="getFiles" resultType="com.haifanbpm.standard.model.vo.CalculateDetailVO$CalculateFileVO"></select>

resultType 中内部类的引用是:CalculateDetailVO$CalculateFileVO

List 判重方法

/**
 * List 判重方法
 * @param <T>
 */
public class ListDistUtils<T> {

    public ListDistUtils() {}

    /**
     * 判断List内是否有数据重复
     * @param rawList
     * @param mapLogic
     * @return
     */
    public List<T> distList(List<T> rawList, Function<? super T,?> mapLogic) {
        return (List<T>) rawList.stream().map(item -> mapLogic.apply(item)).distinct().collect(Collectors.toList());
    }
}

/**
* 使用
*/
ListDistUtils<EmissionUpdateDTO.FactorsParamDTO> listParam = new ListDistUtils<>();
        if (listParam.distList(dto.getFactorsParamList(), EmissionUpdateDTO.FactorsParamDTO:: getName).size() != dto.getFactorsParamList().size()) throw new JeecgBootException("排放因子参数有重复的数据!");

MyBatisPlus 的两种删除

  • 第一种
factorsDataService.removeByIds(factorsDataService.list(new LambdaQueryWrapper<TFactorsData>().eq(TFactorsData::getEmissId, id)).stream().map(TFactorsData::getId).collect(Collectors.toList()));
  • 第二种
calculateFileService.remove(new LambdaQueryWrapper<TCalculateFile>().eq(TCalculateFile::getCalculateId, tCalculate.getId()).eq(TCalculateFile::getType, 1));

List 去重

  • 第一种
list.stream().map(TReportRanges::getRanges).distinct().collect(Collectors.toList());
  • 第二种
list.stream().map(TReportRanges::getRanges).collect(Collectors.toSet()).stream().collect(Collectors.toList()); 
  • 第三种
list.stream().map(TReportRanges::getRanges).collect(Collectors.collectingAndThen(Collectors.toSet(),ArrayList::new));

关于返回 List 数据的封装

  • 方式一
public List<ProvinceVO> getProvinceTreeList() {
    List<TProvince> list = provinceService.list();
    return list.stream().filter(entity -> entity.getParentId()== 0).map(entity -> {
        ProvinceVO provinceVO = new ProvinceVO();
        provinceVO.setId(entity.getId());
        provinceVO.setName(entity.getName());
        provinceVO.setChildren(getChildren(entity, list));
        return provinceVO;
    }).collect(Collectors.toList());
}
  • 方式二
public List<ProvinceVO> getProvinceTreeList() {
    List<TProvince> list = provinceService.list();
    List<ProvinceVO> voList = Lists.newArrayList();
    list.forEach(m -> {
        ProvinceVO provinceVO = new ProvinceVO();
        provinceVO.setId(m.getId());
        provinceVO.setName(m.getName());
        provinceVO.setChildren(getChildren(m, list));
        voList.add(provinceVO);
    });
    return voList;
}

方式一:使用 JDK8 的 stream() 方式进行处理。

方式二:使用传统的 List 进行数据封装。

使用 JDK8 的 stream() 方式,代码会更加简洁,但可读性相对来说不是很好,例如下面一段代码。

tAppList.stream().filter(entity -> entity.getType() == 8).distinct().collect(Collectors.toList()).forEach(item -> {
    appToolList.addAll(appMapper.selectList(new LambdaQueryWrapper<TApp>().eq(TApp::getParentId, item.getId())));
});

子表的保存/更新

  • 方式一
// 先删除
numberColumnService.removeBatchByIds(numberColumnService.list(new LambdaQueryWrapper<TNumberColumn>().eq(TNumberColumn::getColumnId, tColumn.getId())));
// 在保存
if (CollectionUtils.isNotEmpty(dto.getNumList())) {
    dto.getNumList().forEach(c -> {
        TNumberColumn numberColumn = new TNumberColumn();
        numberColumn.setCode(c.getCode());
        numberColumn.setType(c.getType());
        numberColumn.setColumnId(tColumn.getId());
        numberColumnService.save(numberColumn);
    });
}
  • 方式二
// 直接使用 saveOrUpdate 进行保存/更新
if (CollectionUtils.isNotEmpty(dto.getNumList())) {
    dto.getNumList().forEach(c -> {
        TNumberColumn numberColumn = new TNumberColumn();
        numberColumn.setCode(c.getCode());
        numberColumn.setType(c.getType());
        numberColumn.setColumnId(tColumn.getId());
        numberColumnService.saveOrUpdate(numberColumn);
    });
}

方式一:先删除之前的数据,在保存最新的数据。

方式二:直接通过方法 saveOrUpdate 进行保存/更新操作。

try { } catch { } 和 try( ) { } catch { }

  • 方式一
public static String setMd5(MultipartFile file) throws NoSuchAlgorithmException, IOException {
    // 计算MD5
    MessageDigest md = MessageDigest.getInstance("MD5");
    try (InputStream inputStream = file.getInputStream()) {
        byte[] buffer = new byte[1024];
        int bytesRead;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            md.update(buffer, 0, bytesRead);
        }
    }
    byte[] md5Bytes = md.digest();
    StringBuilder md5Hex = new StringBuilder();
    for (byte b : md5Bytes) {
        md5Hex.append(String.format("%02x", b));
    }
    return md5Hex.toString();
}
  • 方式二
public static String setMd5(MultipartFile file) throws NoSuchAlgorithmException, IOException {
    // 计算MD5
    MessageDigest md = MessageDigest.getInstance("MD5");
    InputStream inputStream = file.getInputStream();
    try {
        byte[] buffer = new byte[1024];
        int bytesRead;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            md.update(buffer, 0, bytesRead);
        }
    } finally {
        inputStream.close();
    }
    byte[] md5Bytes = md.digest();
    StringBuilder md5Hex = new StringBuilder();
    for (byte b : md5Bytes) {
        md5Hex.append(String.format("%02x", b));
    }
    return md5Hex.toString();
}

方式一:使用 try () {} catch {} 的方式,如果操作文件流相关的类,那么不需要手动关闭文件流。

方式二:使用 try {} catch {} 的方式,如果操作文件流相关的类,那么需要手动关闭文件流。

如果方法里有事务并且还有 try catch 块,这个时候,错误最好往上抛出,而不是捕获。


文章作者: L Q
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 L Q !
  目录