一、项目需求
需求先了解
- 选择时间间隔 - 点击’查询按钮’查询数据 - 用echarts可视化数据。
草图说逻辑
- 先用一张草图来说明本篇文章的逻辑
注:本篇博客只讨论,mybatis查询数据技术,如你想了解相关技术请移步到我之前的博文:
- 关于日期控件的使用:WdatePicker日期控件的使用
- 关于ajax发送post请求:ajax post 服务器用request.getParameter(“”)拿不到值
二、技术点实现
参数获取
- 从路径中拿到需要的参数(不是本章重点,故省略)
mybaitis获取数据
- 搭好框架,调用方法,利用mybatis获取数据库数据(不是本章重点,故省略)
后端返回Json数据
- 上图中,dateMap是mybatis映射方法getHistoryDataByDate的参数 存入了三个参数:动态表名 ‘tableName’=tableName,起始日期 ‘dStart’=dStart,结束日期 ‘dEnd’=dEnd。
Sql语句
- 首先,看看我的sql语句是怎么写的
<select id="getHistoryDataByDate" parameterType="java.util.HashMap" resultType="java.util.HashMap">
select * from ${tableName}
<where>
<if test="dStart!=null">
<![CDATA[ and DATE_FORMAT(#{dEnd}, '%Y-%m-%d %H:%T:%s') >=
DATE_FORMAT(#{dStart}, '%Y-%m-%d %H:%T:%s') ]]>
</if>
<if test="dEnd!=null">
<![CDATA[ and DATE_FORMAT(time, '%Y-%m-%d %H:%T:%s') <=
DATE_FORMAT(#{dEnd} , '%Y-%m-%d %H:%T:%s') ]]>
</if>
</where>
order by time desc
</select>
为了让大家看的清晰点,上一张图是有必要的
- 然后,再说明一下Sql语句里的重点
1.为什么使用Map类型传参?
答:使用Map类型传参,在获取value时,可以直接写key,如#{dStart},表示获取Map中key=dStart的值。
或许你会有疑问,为什么不用注解方式传参?像这样:
Map<String, Object> getData(@Param(value="tableName") String tableName);
如果真的这么干了,当你需要传多个参数时,方法参数列表就会拖的很长,不美观,像这样:
List<Object>getHistoryDataByDate(@Param(value="tableName")String tableName,@Param(value="dStart") Date dStart,@Param(value="dEnd") Date dEnd);
总之,使用Map传参,优美,简洁,大方,值得信赖。
2.为什么使用${tableName},而不是用#{tableName}?
答:这是mybatis预编译与非预编译问题。
${}会被mybatis替换成参数值。如:我传入的tableName=User,就会select xxx from User,从而实现了动态添加表名。
#{}会被替换成问号?,如:select xxx from User where time between ? and ?
参考博客:浅谈 Mybatis中的 ${ } 和 #{ }的区别
3.if test 语句怎么使用?
- 判断条件写在一起会怎么呢,像这样
<if test="dStart!=null and dStart!=''">
<![CDATA[ and DATE_FORMAT(time, '%Y-%m-%d %H:%T:%s')>= DATE_FORMAT(#{dStart}, '%Y-%m-%d %H:%T:%s') ]]>
</if>
<if test="dEnd!=null and dEnd!=''">
<![CDATA[ and DATE_FORMAT(time, '%Y-%m-%d %H:%T:%s') <= DATE_FORMAT(#{dEnd}, '%Y-%m-%d %H:%T:%s') ]]>
</if>
No Picture You Say A JB:
类型转化异常:
java.lang.IllegalArgumentException: invalid comparison: java.util.Date and java.lang.String
参考文章:mybatis异常invalid comparison: java.util.Date and java.lang.String
4.<![CDATA[ ]]>
是什么?会什么要使用它?
答:<![CDATA[ ]]>
里面的语句不用解析,该是啥样子就是啥样子,不会被Mybatis转译掉。
5.为什么传入的起止日期类型是Date类型就可以查询数据库的datetime类型日期呢?
答:因为java中的java.util.Date 对应mysql中的datetime
6.返回类型为什么是Map?为什么方法的返回值又是List<Objtect>
呢?
首先,若是想要返回list类型参数,即不能直接指定为List,或者AarrayList,因为在这里。
然后,为什么指定了resultType=”java.util.HashMap”,方法会用List<Objtect>
接收了呢?原因mybatis有默认返回类型。
最后,看看我resultType=”java.util.HashMap”的返回结果
可以看出list里有四条数据,每条数据都是一个map<String,Object>
.
当你你遇到“ A query was run and no Result Maps were found for the Mapped Statement ‘cn.edu.hdu.Dao.FactoryMapper.getHistoryDataByDate’. It’s likely that neither a Result Type nor a Result Map was specified.”,就是这个原因。