首先记录的是在任务中遇到的问题,使用PageHelper只是其中的一方面(最后并没有用),所以想深入学习PageHelper的童鞋可以移步到其他博客啦~
在这里提供两个链接:
PageHelper的GitHub地址
别人写的一个PageHelper分页查询方法
下面开始从头到尾记录下任务中的问题和我的解决方法
主要目的是查询数据,返回的是给定的日期中,不同条件下的数据及日环比。即:
(1)给定日期( startDate 2018-08-01 endDate 2018-08-20 )
(2)给定其他查询参数(bucket、business、platform等)
查询满足给定的条件下的数据(PV、UV、ClickPV、ClickUV)及日环比(2018-08-01 PV PVChange)
需要从MySQL查找数据量较大,从查找到显示用时较长。有两方面原因:
(1)查找数据时间较短,但前端显示加载时间较长。导致这个问题出现的原因就是返回数据量大,这种情况使用分页功能,返回给定页面的数据比较合适。
(2)在MyBaits中计算变化时耗时较长。最好是只在SQL中进行数据的查询,返回结果后在Impl中进行日环比等变化数据的计算。
方法:使用MySQL的limit
分页查询
代码格式:
limit (pageNumber-1)*pageSize, pageSize
查询数据实际代码:
select dt, (a.pv, a.pv-b.pv)/b.pv as change
from(
select dt, pv
from table
where dt between #{a} and #{b} and xx = #{xx} and xx = #{xx}
) a
left outer join(
select dt, pv
from table
where dt between DATE_SUB(#{a},INTERVAL 1 day) and DATE_SUB(#{b},INTERVAL 1 day) and xx = #{xx} and xx = #{xx}
) b
on a.dt = b.dt and a.xx = b.xx
order by dt, xx, xx
<if test = "offset >= 0 and pSize >= 0">
limit #{offset}, #{pSize}
if>
使用
#{offset}
的原因是好像不支持代码中直接计算 offset 值,所以我在Service层计算出 offset 值offset = (pageNumber - 1) * pageSize
使用条件的原因是查询满足条件的记录数是不应该限定分页条件,这样在调用DAO的查询条目数方法时直接传入 -1,-1即可
查询满足要求数据记录条目数
select count(1)
from(
xxxxxxxxxxxxx
)a
可以明显的看出在步骤一中查询数据的条目数和查询数据使用了相同的代码,xml文件中代码大量冗余,重复执行针对方法一的问题,网上有不少解决方法,其中SpringMVC提供了 PageHelper
分页插件。下面简单说一下使用方法:
<dependency>
<groupId>com.github.pagehelpergroupId>
<artifactId>pagehelperartifactId>
<version>4.1.6version>
dependency>
id = "sqlSessionFactory" class = "org.mybatis.spring.SqlSessionFactoryBean">
<property name = "dataSource" ref = "dataSource"/>
<property name = "configLocation" value = "classpath:/mybatis/mybatis-config.xml"/>
<property name = "mapperLocations" value = "classpath:/mappers/*.xml"/>
<property name = "plugins">
class = "com.github.pagehelper.PageHelper">
<property name = "properties">
dialet = mysql
rowBoundsWithCount = true
property>
property>
PageHelper.startPage(pageNum, pageSize);
PageHelper.orderBy("dt asc");
List list = xxxDao.getOrderData(xxx,xxx,xxx);
PageInfo pageInfo = new PageInfo(list);
int allSize = pageInfo.getTotal(); //返回总记录条数
List<> res = pageInfo.getList(); //返回分页记录
在使用了上述的方法后发现,还是有部分页面加载时间过长。导致这个问题出现的原因就是执行DAO方法(SQL查询语句)时间过长,解决方法如上所述:SQL只负责查数据,返回的数据在Service层中进行处理。
所以,查询语句变成了
select dt, pv, "0" as change
-- 因为resultMap规定好了,所以还是要添加上change字段
from table
order by dt, xx, xx
因为我们需要计算日环比,所以在查询日期时要用一天前作为startDate。注意到因为我们查询的日期发生变化,所以在这里进行分页操作会使数据缺失,所以分页操作放到计算日环比时进行。
在接收到MyBatis传回来的数据后需要对其进行处理:计算变化及分页。
首先对数据进行预处理:
在进行日期和其他条件的判断时用到了Java的日期和反射相关概念,用于计算给定数据日期的前一天/七天/一年;以及找到给定数据的列字段(因为返回数据格式有多种,无法给定具体的数据列字段)
在计算日环比时要注意:上一天的数据不应该仅仅满足 dt = 前一天,还要满足其他数据列数值相同(就是SQL中的 where)
在进行完上述操作后,从点击到显示的速度大大提高。
level+1
最大的教训就是:写逻辑前一定要想清楚啊。。。