这段代码来源于开发中实例,源代码如下:
public void removeProjectUser(ProjectUserDto projectUserDto) {
if (Optional.ofNullable(projectUserDto.getProjectId()).isPresent()) {
if (!projectUserDto.getUserIds().isEmpty() && projectUserDto.getUserIds().size() > 0) {
projectUserDto.getUserIds().forEach(item -> {
userProjectMapper.delete(Wrappers.<UserProject>update().lambda().eq(UserProject::getProjectId, projectUserDto.getProjectId()).eq(UserProject::getUserId, item));
});
}
}
}
参数类如下:
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ProjectUserDto {
private Long projectId;
private List<Long> userIds;
}
我们可以看到,这段业务代码一共就4行,为了我的接口不报,我的if判断就占据了“半壁江山”,这使我的代码看起来像屎一样,同时我还在foreach中进行了循环删除,要知道我们的接口最耗时就是操作数据库。这样做无疑就是让原本贫穷的家庭完全遭不住。
但是我们仔细想一下,为什么我们要做那么多的逻辑判断呢?
其实我们就是害怕别人会不按你的要求来传参数,导致接口发生一些意想不到的错。那为什么我会害怕呢?因为我没有给到别人提示信息。我们找到源头所在了,我们就要给他足够的提示信息,到时候他自己瞎鸡儿传参数造成异常,我们也让他没法甩锅。
所以优化一下:
参数类:
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ProjectUserDto {
@ApiModelProperty(required = true)
@NotBlank(message = "projectId不能为空字符串")
private Long projectId;
@ApiModelProperty(required = true)
@NotNull(message = "userIds不能为空")
private List<Long> userIds;
}
业务代码:
@Override
public void removeProjectUser(ProjectUserDto projectUserDto) {
userProjectMapper.delete(Wrappers.<UserProject>update().lambda().in(UserProject::getUserId, projectUserDto.getUserIds())
.and(up -> up.eq(UserProject::getProjectId, projectUserDto.getProjectId())));
}
然后我们还可以和前端定好规矩,告诉他这个字段有值你就传,没值就不传,亦或其他规矩。然后我们的校验代码就能少更多。
这样一搞,有没有发现自己已经从一个油头满面的男人化身为一个清秀的男孩了呢!!!男的见到你都想和你1V1男人大战了!
另外我们还可以从时间复杂度来分析一下我们优化前后的代码执行效率,时间复杂度从O(n)降到了O(1)。
by the way : 可能会有人说,我经常在for循环中写增删改查数据库的操作,也没见有多慢啊。如果你使用的是myBatis的话,你可以去了解一下mybatis的一级缓存和二级缓存。