空值处理:分不清楚的null和恼人的空指针

·.### 常见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();

你可能感兴趣的:(java,数据库,java,开发语言)