java查詢近七日數(shù)據(jù)功能的實現(xiàn)
前文
在開寫之前 先來看實現(xiàn)的思路
1.編寫SQL 根據(jù)這七天的日期作為條件查詢數(shù)據(jù)庫
2.獲取Java內(nèi)每次從今天開始到前六天的日期數(shù)據(jù)
3.將查詢出來數(shù)據(jù)做邏輯處理 之后返回json字符串
4.前端使用ajax對接接口 將獲取的數(shù)據(jù)對接到echarts表圖上面
注意 如果你只是看如何獲取近七天的數(shù)據(jù)只看 1 2 3即可
編寫SQL 根據(jù)這七天的日期作為條件查詢數(shù)據(jù)庫
說了實現(xiàn)思路 那么現(xiàn)在看一眼我的表結構是什么樣子的
這里看到一共是7條數(shù)據(jù) 一共是 3條26號 4條25號 1條23號的數(shù)據(jù)
那么我們查詢出來 按每日查詢 有數(shù)據(jù)的顯示幾條數(shù)量
上SQL
SELECT COUNT( * ) AS 'count', DATE_FORMAT( start_task_time, '%Y-%m-%d' ) AS date FROM task WHERE DATE_FORMAT( start_task_time, '%Y-%m-%d' ) IN ( '2020-10-27', '2020-10-26', '2020-10-25', '2020-10-24', '2020-10-23', '2020-10-22', '2020-10-21' ) GROUP BY DATE_FORMAT( start_task_time, '%Y-%m-%d' ) ORDER BY DATE_FORMAT( start_task_time, '%Y-%m-%d' ) DESC;
查詢出來的效果圖
那么現(xiàn)在先來講解一下sql 我是數(shù)據(jù)庫里面時間是帶了時分秒 而查詢的條件日期是不帶時分秒的 這句話的意思是日期格式轉(zhuǎn)換 轉(zhuǎn)換成年月日 去掉時分秒
DATE_FORMAT( start_task_time, '%Y-%m-%d' )
中間的這個是要查詢的字段
現(xiàn)在把SQL拆開來看 先看第一部分
sql的第一部分很好理解 第一個是查詢出整表共有幾條數(shù)據(jù) ,第二個是查詢出時間 AS的意思是字段取別名 。
現(xiàn)在查詢出來的數(shù)據(jù)是 整表共8條數(shù)據(jù) 第一條的數(shù)據(jù)的時間是2020-10-25日
現(xiàn)在來看SQL的第二段
where DATE_FORMAT( start_task_time, ‘%Y-%m-%d’ ) 是要查詢的條件我們根據(jù)日期條件進行查詢 由于是一次查詢七天的 所以需要使用 IN 一個字段多個條件。
后面的group by 分組 每一個日期條件查詢出來的時間 進行分組 并顯示共有幾條 。
最后一個order by 排序
OK! 現(xiàn)在看完了sql 來看最后的查詢結果 。
現(xiàn)在發(fā)現(xiàn)如果哪一天有數(shù)據(jù)的話是可以查詢出來并分組的,如何沒有數(shù)據(jù)是查詢不出來的 。
但是我們查詢出近七天的數(shù)據(jù),如果沒有值就補全為0。
獲取Java內(nèi)每次從今天開始到前六天的日期數(shù)據(jù)
補全剩下沒有日期的數(shù)據(jù),這里就需要我們Java邏輯來實現(xiàn)了。
首先剛剛的sql語句條件是自己寫的 在java里面我們可不能手寫要每次都動態(tài)的獲取從今天開始到前六日的日期數(shù)據(jù)共七天。
那么上Java代碼 獲取近七天的日期
//獲取近七天日期 public static List<String> getSevenDate() { List<String> dateList = new ArrayList<>(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); for (int i = 0; i < 7; i++) { Date date = DateUtils.addDays(new Date(), -i); String formatDate = sdf.format(date); dateList.add(formatDate); } return dateList; }
將查詢出來數(shù)據(jù)做邏輯處理 之后返回json字符串
在java中獲取到了最新的近七天的日期 現(xiàn)在將日期和sql結合 在項目中查詢出數(shù)據(jù)來。
現(xiàn)在看接口,先看前兩句,第一句是獲取近七天數(shù)據(jù),我把代碼封裝到工具類中了,直接調(diào)用的,第二句是將生成的日期作為參數(shù),執(zhí)行查詢方法
這里看Mapper foreach 當中collection 傳的是map就寫map 傳list就寫list 這里咱們查詢方法 默認就寫list就行,item是集合中每一個元素進行迭代時的別名, 傳的參數(shù)名叫什么這個就叫什么就可以。 其他的默認不用管
<select id="sevenDaysCompleteTask" resultType="com.example.demo.bean.Task"> SELECT COUNT(*) AS 'FinishTheTask', DATE_FORMAT(start_task_time,'%Y-%m-%d') AS start_task_time FROM task WHERE is_delete='0' and DATE_FORMAT(start_task_time, '%Y-%m-%d') IN <foreach collection="list" item="sevenDate" separator="," open="(" close=")"> #{sevenDate} </foreach> GROUP BY DATE_FORMAT(start_task_time, '%Y-%m-%d') ORDER BY DATE_FORMAT(start_task_time, '%Y-%m-%d') DESC; </select>
寫完后我們測試一下看看查詢出來的數(shù)據(jù)是什么樣子
用postman測試了一下接口和在數(shù)據(jù)庫查詢返回的數(shù)據(jù)是一樣的
那么現(xiàn)在用java將沒有的日期和數(shù)量進行補全
在開始寫之前說一下編寫思路
現(xiàn)在知道生成的日期長度是7 而數(shù)據(jù)庫查詢出來的數(shù)據(jù)長度是不一定的 因為只有那個日期有數(shù)據(jù)的話才能查詢出來。
實現(xiàn)思路是 創(chuàng)建一個空的arraylist集合來放我們的封裝類,循環(huán)創(chuàng)建封裝類要創(chuàng)建七個,之后循環(huán)拿生成的時間和數(shù)據(jù)庫查詢出的時間做比較,如果一致就將查詢出來的數(shù)據(jù)添加進封裝類中,如果不一致就設置為0,因為我們要有七天的數(shù)據(jù),所以要有七條數(shù)據(jù),每一條數(shù)據(jù)一個封裝類,共七個,之后循環(huán)的將封裝類添加進arraylist集合中。
我不知道大家能不能看明白我所表達的意思 ,如果不明白也沒關系,去看代碼一句一句理解意思。
下面我上代碼 我會一句一句解釋意思
第三句創(chuàng)建一個arraylist對象 這個就是我們最后要返回的集合 這個不難理解
第四句 for循環(huán) 長度是我們生成日期數(shù)組長度 也就是七個
第五句 創(chuàng)建封裝類 外圈循環(huán)七次 一共會創(chuàng)建七個封裝類 一個封裝類代表一條數(shù)據(jù)
第六句 創(chuàng)建boolean類型變量 ,用來判斷生成的日期和查詢出的日期是否一致,默認為false
第七句 創(chuàng)建小循環(huán) 目的是每次小循環(huán)都去循環(huán)查詢出來的日期 一個一個的跟生成出的日期比較,如果一致就將查詢出的數(shù)據(jù)添加進封裝類中,并且設置boolean類型為true 不讓進入設置0的判斷,并結束此次小循環(huán),開始第二次大循環(huán)。
第八句 將查詢出的數(shù)據(jù)添加進封裝類中
第九句 設置boolean類型為true
第十句 結束此次小循環(huán) break
第十一句 每次大循環(huán)都要判斷 是否進入了循環(huán)內(nèi)部判斷 如果進入就不設置0 如果沒有進入就設置為0
第十二句 將每次的封裝類添加到list集合中 并最后返回
上面圖片有點誤差 最后的list要放到外面
@ResponseBody @RequestMapping("/sevenDaysCompleteTask") public List<Task> sevenDaysCompleteTask(){ try { //獲取近七天日期 List<String> sevenDate = ConFig.getSevenDate(); //查詢近七天完成任務數(shù)量方法 List<Task> tasks = healthCommissionService.sevenDaysCompleteTask(sevenDate); //創(chuàng)建一個arraylist對象 List<Task> list=new ArrayList<>(); //外層七天循環(huán) 循環(huán)七次 for (int i=0;i<sevenDate.size();i++){ //創(chuàng)建封裝類對象 循環(huán)七次 創(chuàng)建七個 Task task=new Task(); //將近七天日期添加進封裝類中 task.setStart_task_time(sevenDate.get(i)); boolean bool=false; //創(chuàng)建內(nèi)循環(huán) 根據(jù)查詢出已有的數(shù)量 循環(huán)次數(shù) for (int m=0;m<tasks.size();m++){ if (sevenDate.get(i).equals(tasks.get(m).getStart_task_time())){ task.setFinishTheTask(tasks.get(m).getFinishTheTask()); bool=true; break; } } if (!bool) { task.setFinishTheTask("0"); } list.add(task); } return list; }catch (Exception e) { LOG.error("錯誤信息", e); return null; } }
好了 java的邏輯已經(jīng)完成了 最后看一下返回的數(shù)據(jù)
現(xiàn)在成功的吧沒有數(shù)據(jù)的日期也添加到集合并且返回了
前端使用ajax對接接口 將獲取的數(shù)據(jù)對接到echarts表圖上面
OK??! 最后一步 對接echarts圖表
打開html 在圖表的js里面先創(chuàng)建兩個 數(shù)組 一個代表時間 一個代表數(shù)量 也就是圖表當中的這兩部分
使用ajax 對接接口 用each循環(huán)將返回的json數(shù)據(jù)添加進兩個數(shù)組中
將數(shù)據(jù)添加進去后 把數(shù)組放入echarts圖表中
這里就結束了 看成品效果
最后放js代碼 比較長
<!--完成任務七天數(shù)量條形圖js--> <script> //七天時間變量 var time1=[]; //近七天完成任務數(shù)量 var numberofelderly1=[]; $(function () { $.ajax({ type:"post", url:"sevenDaysCompleteTask", async: false, datatype: "json", success:function (data){ $.each(data, function(i,item) { time1.push(item.start_task_time); numberofelderly1.push(item.finishTheTask); }) var myChart = echarts.init(document.getElementById('main')); const CubeLeft = echarts.graphic.extendShape({ shape: { x: 20, y: 10 }, buildPath: function(ctx, shape) { const xAxisPoint = shape.xAxisPoint const c0 = [shape.x, shape.y] const c1 = [shape.x - 9, shape.y - 9] const c2 = [xAxisPoint[0] - 9, xAxisPoint[1] - 9] const c3 = [xAxisPoint[0], xAxisPoint[1]] ctx.moveTo(c0[0], c0[1]).lineTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).closePath() } }) const CubeRight = echarts.graphic.extendShape({ shape: { x: 10, y: 10 }, buildPath: function(ctx, shape) { const xAxisPoint = shape.xAxisPoint const c1 = [shape.x, shape.y] const c2 = [xAxisPoint[0], xAxisPoint[1]] const c3 = [xAxisPoint[0] + 18, xAxisPoint[1] - 9] const c4 = [shape.x + 18, shape.y - 9] ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0], c4[1]).closePath() } }) const CubeTop = echarts.graphic.extendShape({ shape: { x: 0, y: 0 }, buildPath: function(ctx, shape) { const c1 = [shape.x, shape.y] const c2 = [shape.x + 18, shape.y - 9] const c3 = [shape.x + 9, shape.y - 18] const c4 = [shape.x - 9, shape.y - 9] ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0], c4[1]).closePath() } }) echarts.graphic.registerShape('CubeLeft', CubeLeft) echarts.graphic.registerShape('CubeRight', CubeRight) echarts.graphic.registerShape('CubeTop', CubeTop) const MAX = numberofelderly1 const VALUE = numberofelderly1 option = { // backgroundColor: "#010d3a", title: { text: '', top: 32, left: 18, textStyle: { color: '#00F6FF', fontSize: 24 } }, /*調(diào)整表格大小*/ grid: { left: 0, right: 0, bottom: '6%', top: 90, containLabel: true }, xAxis: { type: 'category', data: time1, axisLine: { show: true, lineStyle: { color: 'white' } }, offset: 20, axisTick: { show: false, length: 9, alignWithLabel: true, lineStyle: { color: '#7DFFFD' } }, axisLabel: { fontSize: 10 } }, yAxis: { type: 'value', axisLine: { show: true, lineStyle: { color: 'white' } }, splitLine: { show: false }, axisTick: { show: false }, axisLabel: { fontSize: 15 }, boundaryGap: ['0', '20%'] }, series: [{ type: 'custom', renderItem: function(params, api) { const location = api.coord([api.value(0), api.value(1)]) return { type: 'group', children: [{ type: 'CubeLeft', shape: { api, xValue: api.value(0), yValue: api.value(1), x: location[0], y: location[1], xAxisPoint: api.coord([api.value(0), 0]) }, style: { fill: 'rgba(7,29,97,.6)' } }, { type: 'CubeRight', shape: { api, xValue: api.value(0), yValue: api.value(1), x: location[0], y: location[1], xAxisPoint: api.coord([api.value(0), 0]) }, style: { fill: 'rgba(10,35,108,.7)' } }, { type: 'CubeTop', shape: { api, xValue: api.value(0), yValue: api.value(1), x: location[0], y: location[1], xAxisPoint: api.coord([api.value(0), 0]) }, style: { fill: 'rgba(11,42,106,.8)' } }] } }, data: MAX }, { type: 'custom', renderItem: (params, api) => { const location = api.coord([api.value(0), api.value(1)]) return { type: 'group', children: [{ type: 'CubeLeft', shape: { api, xValue: api.value(0), yValue: api.value(1), x: location[0], y: location[1], xAxisPoint: api.coord([api.value(0), 0]) }, style: { fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ offset: 0, color: '#3B80E2' }, { offset: 1, color: '#49BEE5' } ]) } }, { type: 'CubeRight', shape: { api, xValue: api.value(0), yValue: api.value(1), x: location[0], y: location[1], xAxisPoint: api.coord([api.value(0), 0]) }, style: { fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ offset: 0, color: '#3B80E2' }, { offset: 1, color: '#49BEE5' } ]) } }, { type: 'CubeTop', shape: { api, xValue: api.value(0), yValue: api.value(1), x: location[0], y: location[1], xAxisPoint: api.coord([api.value(0), 0]) }, style: { fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ offset: 0, color: '#3B80E2' }, { offset: 1, color: '#49BEE5' } ]) } }] } }, data: VALUE }, { type: 'bar', label: { normal: { show: true, position: 'top', formatter: (e) => { switch (e.name) { case '10kV線路': return VALUE[0] case '公用配變': return VALUE[1] case '35kV主變': return VALUE[2] case '水': } }, fontSize: 16, color: '#38ff9f', offset: [4, -25] } }, itemStyle: { color: 'transparent' }, data: MAX }] } myChart.setOption(option); } }) }) </script>
到此這篇關于java查詢近七日數(shù)據(jù)功能的實現(xiàn)的文章就介紹到這了,更多相關java實現(xiàn)查詢數(shù)據(jù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
詳解Spring boot使用Redis集群替換mybatis二級緩存
本篇文章主要介紹了詳解Spring boot使用Redis集群替換mybatis二級緩存,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-05-05SpringBoot中MyBatis使用自定義TypeHandler的實現(xiàn)
本文主要介紹了SpringBoot中MyBatis使用自定義TypeHandler,當默認的類型映射不能滿足需求時,自定義?TypeHandler?就非常有用,具有一定的參考價值,感興趣的可以了解一下2024-08-08MyBatis處理mysql主鍵自動增長出現(xiàn)的不連續(xù)問題解決
本文主要介紹了MyBatis處理mysql主鍵自動增長出現(xiàn)的不連續(xù)問題解決,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-09-09