·.### 常见Null问题
客户端给服务端的一个数据是 null,那么其意图到底是给一个空值,还是没提供值呢?再比如,数据库中字段的 NULL 值,是否有特殊的含义呢,针对数据库中的 NULL 值,写 SQL 需要特别注意什么呢?
常见NullPointerException异常问题
1:参数值是 Integer等包装类型时,使用时因为自动拆装箱问题出现空指针异常
2:字符串比较出现空指针异常
3:Hash容器存入null会报错,比如诸如ConcurrentHashMap 这样的容器不支持 Key 和 Value 为 null,强行 put null 的 Key 或 Value 会出现空指针异常
;
4:A对象包含B,在通过A获取B时,木有对字段判空就练级调用B的方法,会出现空指针异常
5:方法或者和远程服务的List不是空,而是null,木有进行判空就直接调用List的方法会出现空指针异常
解决方法:使用Lambad来解决:
1:对于 Integer 的判空,可以使用 Optional.ofNullable 来构造一个 Optional,然后使用 orElse(0) 把 null 替换为默认值再进行 +1 操作。
2:对于 String 和字面量的比较,可以把字面量放在前面,比如"OK".equals(s),这样即使 s 是 null 也不会出现空指针异常;而对于两个可能为 null 的字符串变量的 equals 比较,可以使用 Objects.equals,它会做判空处理。
private List<String> rightMethod(FooService fooService, Integer i, String s, String t) {
log.info("result {} {} {} {}", Optional.ofNullable(i).orElse(0) + 1, "OK".equals(s), Objects.equals(s, t), new HashMap<String, String>().put(null, null));
Optional.ofNullable(fooService)
.map(FooService::getBarService)
.filter(barService -> "OK".equals(barService.bar()))
.ifPresent(result -> log.info("OK"));
return new ArrayList<>();
}
@GetMapping("right")
public int right(@RequestParam(value = "test", defaultValue = "1111") String test) {
return Optional.ofNullable(rightMethod(test.charAt(0) == '1' ? null : new FooService(),
test.charAt(1) == '1' ? null : 1,
test.charAt(2) == '1' ? null : "OK",
test.charAt(3) == '1' ? null : "OK"))
.orElse(Collections.emptyList()).size();
}
数据库中Null
1:通过 sum 函数统计一个只有 NULL 值的列的总和,比如 SUM(score);
2:select 记录数量,count 使用一个允许 NULL 的字段,比如 COUNT(score);
3:使用 =NULL 条件查询字段值为 NULL 的记录,比如 score=null 条件。
解决方法
解决1:MySQL 中 sum 函数没统计到任何记录时,会返回 null 而不是 0,可以使用 IFNULL 函数把 null 转换为 0;
解决2:MySQL 中 count 字段不统计 null 值,COUNT(*) 才是统计所有记录数量的正确方式。
解决三:MySQL 中使用诸如 =、<、> 这样的算数比较操作符比较 NULL 的结果总是 NULL,这种比较就显得没有任何意义,需要使用 IS NULL、IS NOT NULL 或 ISNULL() 函数来比较。
修改之后代码
@Query(nativeQuery = true, value = "SELECT IFNULL(SUM(score),0) FROM `user`")
Long right1();
@Query(nativeQuery = true, value = "SELECT COUNT(*) FROM `user`")
Long right2();
@Query(nativeQuery = true, value = "SELECT * FROM `user` WHERE score IS NULL")
List<User> right3();