最近给数据平台的模型查询部分加了一个查询缓存。通过Spring AOP实现,思路是将查询结果通过gson序列化后存储在HBase中。
List<Map<String,Object>> query(String sql)
对Service的逻辑完全无修改。
在功能准备上线的时候发现某个漏斗查询第一次查询结果正常,后面的查询(走的是缓存)会报一个空指针异常。
于是在出问题的代码上设断点调试。发现语句中的大写字段名在查询结果中被转成了小写。还是很奇怪,那第一次查询
的时候为什么不会跑出空指针异常呢?
仔细对比两次运行结果,发现Spring的JdbcTemplate返回的是LinkedCaseInsensitiveMap,而Gson反序列化产生的Map是一个LinkedTreeMap。
前者的key是大小写不敏感的而后者是大小写敏感的,于是出现两次运行结果的不同。
总结:在面向接口编程时数据的实际类型比较容易被忽视,在调试代码的过程中既要关注数据的内容,也要关注数据的实际类型。另外数据库的字段和字段别名通常是大小写不敏感的,在程序设计时字段不应该包含大小写信息。