代码经验
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 块,这个时候,错误最好往上抛出,而不是捕获。