前言
现在的项目开发中对于项目中DAO层的操作一般都是使用ORM开发框架,例如MyBatis或者hibernate等。虽然这些全自动半自动的ORM框架为操作DAO层提供了更加便捷的接口,但是原生的sql操作在一些项目中还是运用广泛。
特别是一些需要连表查询或者是定制化sql语句的操作中原生的sql运用尤其广泛。
jdbcTemplate作为一个原生的sql操作模板,使用较为方便。
但是在今天使用的过程中踩了一个坑,和大家分享一下!
使用场景分析
需求:后台有一张表,记录了每天的客户浏览量,标识id,月增长量,日增长量等的数据。现在需要将数据查询出来,按每天的浏览量展示到前端的echarts折现表中,同时在折现表的上方展示当天的浏览量,增长量等的数据。
我的操作:
写了两个接口:
- queryBlend():查询统计数据(总浏览量,上月总和等)
- queryBlendData():查询本月每天的数据放到list中,由前端解析展示到echarts的折线图中。
出错原因
后台在查询数据的时候我是先写的queryBlendData()接口的service和dao,因为每天的数据都是一个item,需要查询一个月的数据,于是我使用queryForList()查询,并将查询结果存储在list中返回给前端。这一步没有问题,数据返回成功,前台显示没有问题。
但是在查询查询统计数据(总浏览量,上月总和等)的时候,我使用的是map,也就是dao层查询数据使用了queryForMap(),结果报错了!!!
查看报错,发现有的数据是因为通过id和data查询的时候没有当天数据,查询结果为空了,queryForMap()就报错了,还有的是因为数据库的表里添加了很多开发人员的测试数据,有的人将插入的时候当日数据和别人写重了(同一天有两条数据),结果使用queryForMap()返回的时候就报错了。
解决办法
- 将查询的queryForMap()替换为queryForList(); 我个人并不推荐这种做法
- 对于数据库做整理,让数据库的当日数据唯一化
queryForMap()替换为queryForList()?因为queryForList()查询后返回的不是一条记录,它可以返回一个集合,查出一条返回一条,查出10条返回十条,这样在查询完后又得做判断,甚至是从多条数据中遍历寻找你要找的数据。但是使用queryForMap()只会返回一条或者是报错。
queryForMap()与queryForList()区别
queryForMap()
- sql 必须能查到数据,不能为 null
- sql 必须能查到数据, 而且仅有一条
- 使用时最好捕捉一下异常,try catch(这样在调用时就知道是数据查询除了问题)
- 返回取值的key, 就是查询列的字段
queryForList()
它查出来是一个集合,没有什么要求,取值前只需要对查询List.size()进行简单的判断即可,然后循环遍历进行取值。