目录
【鸿蒙智能硬件】(五)使用springboot+mybatis构建web服务器端应用-CSDN博客
使用echarts图表组件显示环境监测数据
修改后端代码,封装柱图需要的数据项
EnvDao.java
java
package com.xiyou.dao;
import com.xiyou.entity.Env;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.data.domain.Pageable;
import java.util.List;
/**
* (Env)表数据库访问层
*
* @author makejava
* @since 2026-03-12 10:04:37
*/
@Mapper
public interface EnvDao {
/**
* 通过ID查询单条数据
*
* @param id 主键
* @return 实例对象
*/
Env queryById(Integer id);
/**
* 查询指定行数据
*
* @param env 查询条件
* @param pageable 分页对象
* @return 对象列表
*/
List<Env> queryAllByLimit(@Param("env") Env env, @Param("pageable") Pageable pageable);
/**
* 统计总行数
*
* @param env 查询条件
* @return 总行数
*/
long count(@Param("env") Env env);
/**
* 新增数据
*
* @param env 实例对象
* @return 影响行数
*/
int insert(Env env);
/**
* 批量新增数据(MyBatis原生foreach方法)
*
* @param entities List<Env> 实例对象列表
* @return 影响行数
*/
int insertBatch(@Param("entities") List<Env> entities);
/**
* 批量新增或按主键更新数据(MyBatis原生foreach方法)
*
* @param entities List<Env> 实例对象列表
* @return 影响行数
* @throws org.springframework.jdbc.BadSqlGrammarException 入参是空List的时候会抛SQL语句错误的异常,请自行校验入参
*/
int insertOrUpdateBatch(@Param("entities") List<Env> entities);
/**
* 修改数据
*
* @param env 实例对象
* @return 影响行数
*/
int update(Env env);
/**
* 通过主键删除数据
*
* @param id 主键
* @return 影响行数
*/
int deleteById(Integer id);
//获取温度湿度和气味的前5条记录值
List<Env> getEnvListTop5();
/**
* 饼图的数据构成
* 获取温度湿度和气味的平均值
* */
List<Map<String,Object>> findAvgEnvData();
}
EnvDao.xml
java
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xiyou.dao.EnvDao">
<resultMap type="com.xiyou.entity.Env" id="EnvMap">
<result property="id" column="id" jdbcType="INTEGER"/>
<result property="tmp" column="tmp" jdbcType="VARCHAR"/>
<result property="him" column="him" jdbcType="VARCHAR"/>
<result property="gan" column="gan" jdbcType="VARCHAR"/>
<result property="cdate" column="cdate" jdbcType="TIMESTAMP"/>
</resultMap>
<!--查询单个-->
<select id="queryById" resultMap="EnvMap">
select
id, tmp, him, gan, cdate
from env
where id = #{id}
</select>
<!--查询指定行数据-->
<select id="queryAllByLimit" resultMap="EnvMap">
select
id, tmp, him, gan, cdate
from env
order by id desc
limit #{pageable.offset}, #{pageable.pageSize}
</select>
<!--统计总行数-->
<select id="count" resultType="java.lang.Long">
select count(1)
from env
</select>
<select id="getEnvListTop5" resultType="com.xiyou.entity.Env">
SELECT * FROM env WHERE 1=1 ORDER BY id DESC LIMIT 0,5
</select>
<!-- 获取温度湿度和气味的平均值用于饼图的数据呈现 -->
<select id="findAvgEnvData" resultType="java.util.Map">
SELECT ROUND(AVG(tmp)) avgtmp,ROUND(AVG(him)) avghim,ROUND(AVG(gan)/10) avggan FROM env WHERE 1=1;
</select>
<!--新增所有列-->
<insert id="insert" keyProperty="id" useGeneratedKeys="true">
insert into env(tmp, him, gan, cdate)
values (#{tmp}, #{him}, #{gan}, #{cdate})
</insert>
<insert id="insertBatch" keyProperty="id" useGeneratedKeys="true">
insert into env(tmp, him, gan, cdate)
values
<foreach collection="entities" item="entity" separator=",">
(#{entity.tmp}, #{entity.him}, #{entity.gan}, #{entity.cdate})
</foreach>
</insert>
<insert id="insertOrUpdateBatch" keyProperty="id" useGeneratedKeys="true">
insert into env(tmp, him, gan, cdate)
values
<foreach collection="entities" item="entity" separator=",">
(#{entity.tmp}, #{entity.him}, #{entity.gan}, #{entity.cdate})
</foreach>
on duplicate key update
tmp = values(tmp),
him = values(him),
gan = values(gan),
cdate = values(cdate)
</insert>
<!--通过主键修改数据-->
<update id="update">
update env
<set>
<if test="tmp != null and tmp != ''">
tmp = #{tmp},
</if>
<if test="him != null and him != ''">
him = #{him},
</if>
<if test="gan != null and gan != ''">
gan = #{gan},
</if>
<if test="cdate != null">
cdate = #{cdate},
</if>
</set>
where id = #{id}
</update>
<!--通过主键删除-->
<delete id="deleteById">
delete from env where id = #{id}
</delete>
</mapper>
EnvService.java
javascript
package com.xiyou.service;
import com.xiyou.entity.Env;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import java.util.Map;
import java.util.List;
/**
* (Env)表服务接口
*
* @author makejava
* @since 2026-03-12 13:54:11
*/
public interface EnvService {
/**
* 通过ID查询单条数据
*
* @param id 主键
* @return 实例对象
*/
Env queryById(Integer id);
/**
* 分页查询
*
* @param env 筛选条件
* @param pageRequest 分页对象
* @return 查询结果
*/
Page<Env> queryByPage(Env env, PageRequest pageRequest);
/**
* 新增数据
*
* @param env 实例对象
* @return 实例对象
*/
Env insert(Env env);
/**
* 修改数据
*
* @param env 实例对象
* @return 实例对象
*/
Env update(Env env);
/**
* 通过主键删除数据
*
* @param id 主键
* @return 是否成功
*/
boolean deleteById(Integer id);
//获取温度湿度和气味的前5条记录值
List<Env> getEnvListTop5();
/**
* 饼图的数据构成
* 获取温度湿度和气味的平均值
* */
List<Map<String,Object>> findAvgEnvData();
}
EnvServiceImpl.java
javascript
package com.xiyou.service.impl;
import com.xiyou.entity.Env;
import com.xiyou.dao.EnvDao;
import com.xiyou.service.EnvService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import java.util.List;
/**
* (Env)表服务实现类
*
* @author makejava
* @since 2026-03-12 10:04:38
*/
@Service("envService")
public class EnvServiceImpl implements EnvService {
@Resource
private EnvDao envDao;
/**
* 通过ID查询单条数据
*
* @param id 主键
* @return 实例对象
*/
@Override
public Env queryById(Integer id) {
return this.envDao.queryById(id);
}
/**
* 分页查询
*
* @param env 筛选条件
* @param pageRequest 分页对象
* @return 查询结果
*/
@Override
public Page<Env> queryByPage(Env env, PageRequest pageRequest) {
long total = this.envDao.count(env);
return new PageImpl<>(this.envDao.queryAllByLimit(env, pageRequest), pageRequest, total);
}
/**
* 新增数据
*
* @param env 实例对象
* @return 实例对象
*/
@Override
public Env insert(Env env) {
this.envDao.insert(env);
return env;
}
/**
* 修改数据
*
* @param env 实例对象
* @return 实例对象
*/
@Override
public Env update(Env env) {
this.envDao.update(env);
return this.queryById(env.getId());
}
/**
* 通过主键删除数据
*
* @param id 主键
* @return 是否成功
*/
@Override
public boolean deleteById(Integer id) {
return this.envDao.deleteById(id) > 0;
}
@Override
public List<Env> getEnvListTop5() {
return this.envDao.getEnvListTop5();
}
public List<Map<String, Object>> findAvgEnvData() {
return envDao.findAvgEnvData();
}
}
EnvController.java
javascript
package com.xiyou.controller;
import com.xiyou.entity.Env;
import com.xiyou.service.EnvService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* (Env)表控制层
*
* @author makejava
* @since 2026-03-12 10:04:35
*/
@RestController
@RequestMapping("env")
public class EnvController {
/**
* 服务对象
*/
@Resource
private EnvService envService;
/**
* 分页查询
*
* @param env 筛选条件
* @param page 当前页数
* @param pagesize 每页记录数
* @return 查询结果
*/
@RequestMapping(value = "/findPageAll")
public Map<String,Object> queryByPage(Env env, Integer page,Integer pagesize) {
page=page==null||page<1?1:page;
pagesize=pagesize==null||pagesize<1?5:pagesize;
//获取PageRequest对象
PageRequest pageRequest=PageRequest.of((page-1),pagesize);
Page<Env> pageEnv=envService.queryByPage(env,pageRequest);
//获取分页的数据
//获取总记录数
long totlcount=pageEnv.getTotalElements();
//获取总页数
Integer totalPage=pageEnv.getTotalPages();
//获取每页记录集合
List<Env> data=pageEnv.getContent();
//将数据封装到Map集合
Map<String,Object> mappage=new HashMap<>();
mappage.put("page",page);
mappage.put("pagesize",pagesize);
mappage.put("totalCount",totlcount);
mappage.put("totalPage",totalPage);
mappage.put("data",data);
return mappage;
}
/**
* 获取温度湿度和气味的前5条记录值
*
* @return 前5条记录值
*/
@RequestMapping(value = "/getEnvListTop5")
public List<Map<String,Object>> getEnvListTop5() {
List<Env> envListTop5 = envService.getEnvListTop5();
//柱状图series的数据项
List<Map<String,Object>> listmap=new ArrayList<>();
//温度的map集合
Map<String,Object> maptmp=new HashMap<>();
maptmp.put("name","温度");
maptmp.put("type","bar");
List<String> tmplist=new ArrayList<>();//存放温度值的集合
//湿度的map集合
Map<String,Object> maphim=new HashMap<>();
maphim.put("name","湿度");
maphim.put("type","bar");
List<String> himlist=new ArrayList<>();//存放湿度值的集合
//气味的map集合
Map<String,Object> mapgan=new HashMap<>();
mapgan.put("name","气味");
mapgan.put("type","bar");
List<String> ganlist=new ArrayList<>();//存放气味值的集合
//遍历envListTop5集合,将温度、湿度和气味值分别添加到tmplist、himlist和ganlist集合中
for (Env env : envListTop5) {
tmplist.add(env.getTmp());
himlist.add(env.getHim());
ganlist.add(Integer.parseInt(env.getGan())/10+"");
}
//将tmplist、himlist和ganlist集合添加到maptmp、maphim和mapgan中
maptmp.put("data",tmplist);
maphim.put("data",himlist);
mapgan.put("data",ganlist);
//将maptmp、maphim和mapgan添加到listmap集合中
listmap.add(maptmp);
listmap.add(maphim);
listmap.add(mapgan);
return listmap;
}
/**
* 饼图的数据构成
* 获取温度湿度和气味的平均值
* */
@RequestMapping(value = "/findAvgEnvData")
public List<Map<String,Object>> findAvgEnvData() {
//series的数据项
List<Map<String,Object>> listmap=new ArrayList<>();
//从数据库获取的数据项
List<Map<String,Object>> listmapdb=envService.findAvgEnvData();
//遍历listmapdb集合,将数据项添加到listmap集合中
Map<String,Object> maptmp=new HashMap<>();
Map<String,Object> maphim=new HashMap<>();
Map<String,Object> mapgan=new HashMap<>();
for (Map<String, Object> map : listmapdb) {
//将name添加到maptmp、maphim和mapgan中
maptmp.put("name","温度");
maphim.put("name","湿度");
mapgan.put("name","气味");
//将数据项添加到maptmp、maphim和mapgan中
maptmp.put("value",map.get("avgtmp"));
maphim.put("value",map.get("avghim"));
mapgan.put("value",map.get("avggan"));
}
listmap.add(maptmp);
listmap.add(maphim);
listmap.add(mapgan);
return listmap;
}
}
前端代码的构建
index.html
javascript
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!--<meta http-equiv="refresh" content="5">-->
<title>环境监测数据列表</title>
<script src="js/jquery-1.9.1.js"></script>
<script src="vue/vue.js"></script>
<script src="vue/vue-resource.js"></script>
<!-- 引入bootstrap样式 -->
<link rel="stylesheet" href="bootstrap/css/bootstrap.css">
<link rel="stylesheet" href="bootstrap/css/bootstrap-theme.css">
<link rel="stylesheet" href="bootstrap/css/style.css">
<script src="bootstrap/js/bootstrap.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.0.0/echarts.min.js"></script>
</head>
<body>
<div id="mainenvtemplate">
<h2 align="center">环境监测数据列表</h2>
<hr/>
<div>
<table class="table table-striped table-hover table-bordered">
<tr align="center">
<td>编号</td>
<td>温度</td>
<td>湿度</td>
<td>气味</td>
<td>日期</td>
</tr>
<tr align="center" v-for="env in envlist">
<td>{{env.id}}</td>
<td>{{env.tmp}}</td>
<td>{{env.him}}</td>
<td>{{env.gan}}</td>
<td>{{env.cdate}}</td>
</tr>
</table>
<!-- 分页 -->
<table class="table table-striped">
<tr align="center">
<td>
<input type="button" value="首页" @click="dofirstPage()">
<input type="button" value="上页" @click="doupPage()">
<input type="button" value="下页" @click="donextPage()">
<input type="button" value="末页" @click="dolastPage()">
</td>
<td>
跳转到第
<input type="text" name="page" id="page" v-model="page">
页
<input type="button" value="确定" @click="dochangePage()">
</td>
<td>{{page}}/{{totalpage}}</td>
</tr>
</table>
</div>
<hr/>
</div>
</div>
<div align="center">
<!-- 显示图表 -->
<div id="echartsdemo" style="width: 100%;height:600px;display: flex;flex-direction: row">
<div id="mainbar" style="width: 600px;height:400px;"></div>
<script type="text/javascript">
//使用jQuery访问后端接口返回的数据
$.getJSON("env/getEnvListTop5", function(resdata) {
console.log(resdata);
//===========柱状图显示=========================================
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('mainbar'));
//使用柱状图显示环境监测数据
// 指定图表的配置项和数据
var option = {
title: {
text: '环境监测数据'
},
tooltip: {},
legend: {
data: ['温度', '湿度', '气味']
},
xAxis: {
data: ['温度', '湿度', '气味']
},
yAxis: {},
series: resdata
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
//==========================柱状图显示结束==============
});
</script>
<!-- 饼形图数据显示区域 -->
<div id="mainpip" style="width: 600px;height:400px;"></div>
<!-- 显示饼形图 -->
<script type="text/javascript">
//使用Jquery显示饼图===================================================
$.getJSON('env/findAvgEnvData',function(resdata){
console.log(resdata);
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('mainpip'));
// 指定图表的配置项和数据
var option = {
title: {
text: '环境监测数据'
},
tooltip: {},
legend: {
data: ['温度', '湿度', '气味']
},
series: [
{
name: '环境监测数据',
type: 'pie',
radius: '55%',
data: resdata
}
]
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
});
//================饼图显示结束========================================
</script>
</div>
</div>
</body>
<script src="js/index.js"></script>
<script>
//实现每隔5秒刷新一次页面
setTimeout(function(){
location.reload(true); // 重新加载页面
}, 5000); // 5000毫秒 = 5秒
</script>
</html>

使用鸿蒙app展示环境监测数据
鸿蒙app开发工具下载
Devecho studio开发工具下载地址:https://developer.huawei.com/consumer/cn/deveco-studio/
不要安装在有中文或者空格和其他特殊字符的目录
新建项目
New-->project--选择application
Application中选择Template Market
修改配置文件,设置网络访问
module.json5
javascript
{
"module": {
"name": "entry",
"type": "entry",
"description": "$string:module_desc",
"mainElement": "EntryAbility",
"deviceTypes": [
"phone",
"tablet",
"2in1"
],
"deliveryWithInstall": true,
"installationFree": false,
"pages": "$profile:main_pages",
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ets",
"description": "$string:EntryAbility_desc",
"icon": "$media:layered_image",
"label": "$string:EntryAbility_label",
"startWindowIcon": "$media:startIcon",
"startWindowBackground": "$color:start_window_background",
"exported": true,
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"action.system.home"
]
}
]
}
],
"extensionAbilities": [
{
"name": "EntryBackupAbility",
"srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets",
"type": "backup",
"exported": false,
"metadata": [
{
"name": "ohos.extension.backup",
"resource": "$profile:backup_config"
}
],
}
],
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
}
]
}
}
修改界面Index.ets
创建images文件夹
复制图片到pages目录的images文件夹
修改Index.ets文件,加入环境监测数据的代码,实现轮播图显示
index.ets
javascript
import { http } from '@kit.NetworkKit';
interface EnvData {
tmp?: string | number;
him?: string | number;
gan?: string | number;
cdate?: string;
}
interface ApiResponse {
data?: EnvData[];
}
@Entry
@Component
struct Index {
@State message: string = 'Hello World';
@State wendu:string = '0';
@State shidu:string = '0';
@State qiwei:string = '0';
@State envDataList: EnvData[] = [];
@State isLoading: boolean = false;
@State errorMessage: string = '';
//编写函数访问服务器后端获取环境信息
async fetchEnvData() {
this.isLoading = true;
this.errorMessage = '';
let httpRequest = http.createHttp();
try {
const response = await httpRequest.request(
'http://192.168.43.246:9000/env/findPageAll',
{
method: http.RequestMethod.GET,
header: {
'Content-Type': 'application/json'
},
connectTimeout: 10000,
readTimeout: 10000
}
);
if (response.responseCode === 200) {
const result: ApiResponse = JSON.parse(response.result as string);
console.log('result.data--->',result.data);
if (result && Array.isArray(result.data)) {
this.envDataList = result.data as EnvData[];
console.log('this.envDataList--->',this.envDataList);
this.wendu = this.envDataList[0].tmp as string;
this.shidu = this.envDataList[0].him as string;
this.qiwei = this.envDataList[0].gan as string;
console.log('this.wendu--->',this.wendu);
console.log('this.shidu--->',this.shidu);
console.log('this.qiwei--->',this.qiwei);
} else if (Array.isArray(result)) {
this.envDataList = result as EnvData[];
}
} else {
this.errorMessage = `请求失败,状态码: ${response.responseCode}`;
}
} catch (error) {
this.errorMessage = `请求异常: ${JSON.stringify(error)}`;
} finally {
httpRequest.destroy();
this.isLoading = false;
}
}
aboutToAppear() {
this.fetchEnvData();
}
build() {
Column() {
// Text(this.message).fontSize(50).width('100%').height(50)
//============================================================轮播图=================
Column() {
Swiper() {
Image("/pages/images/banner.png").width('100%').height('100%').objectFit(ImageFit.Fill)
Image("/pages/images/jdbanner1.jpg").width('100%').height('100%').objectFit(ImageFit.Fill)
Image("/pages/images/jdbanner3.jpg").width('100%').height('100%').objectFit(ImageFit.Fill)
Image("/pages/images/jdbanner4.jpg").width('100%').height('100%').objectFit(ImageFit.Fill)
}
.width('100%')
.height('100%')
.autoPlay(true)
.loop(true)
.interval(3000)
}.width('100%').height('30%').backgroundColor(Color.Red)
//================================================================
//=============现实环境监测数据================================
//环境数据显示区域
Column() {
if (this.isLoading) {
Text('加载中...')
.fontSize(18)
.fontColor('#666')
} else if (this.errorMessage) {
Text(this.errorMessage)
.fontSize(14)
.fontColor('#FF0000')
} else if (this.envDataList.length > 0) {
Text('环境数据列表')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.width('100%')
.margin({ bottom: 10 })
List({ space: 10 }) {
ForEach(this.envDataList, (item: EnvData, index: number) => {
ListItem() {
Column() {
Row() {
Text(`数据 ${index + 1}`)
.fontSize(16)
.fontWeight(FontWeight.Bold)
Text(item.cdate || 'N/A')
.fontSize(14)
.fontColor('#999')
.margin({ left: 10 })
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
Divider()
Row() {
Column() {
Text('温度')
.fontSize(12)
.fontColor('#666')
Text(`${item.tmp || 'N/A'}°C`)
.fontSize(18)
.fontColor('#FF6B6B')
.margin({ top: 5 })
}
.alignItems(HorizontalAlign.Center)
Column() {
Text('湿度')
.fontSize(12)
.fontColor('#666')
Text(`${item.him || 'N/A'}%`)
.fontSize(18)
.fontColor('#4ECDC4')
.margin({ top: 5 })
}
.alignItems(HorizontalAlign.Center)
Column() {
Text('气味')
.fontSize(12)
.fontColor('#666')
Text(`${item.gan || 'N/A'}`)
.fontSize(18)
.fontColor('#45B7D1')
.margin({ top: 5 })
}
.alignItems(HorizontalAlign.Center)
}
.width('100%')
.justifyContent(FlexAlign.SpaceAround)
.padding({ top: 10, bottom: 10 })
}
.width('100%')
.padding(15)
.backgroundColor('#FFFFFF')
.borderRadius(10)
.shadow({ radius: 5, color: '#1F000000', offsetX: 0, offsetY: 2 })
}
})
}
.width('100%')
.layoutWeight(1)
} else {
Text('暂无数据')
.fontSize(16)
.fontColor('#999')
}
}
.width('100%')
.padding(15)
.layoutWeight(1)
//刷新按钮
Button('刷新数据')
.onClick(() => {
this.fetchEnvData();
})
.width('80%')
.height(45)
.fontSize(16)
.margin({ bottom: 20 })
.backgroundColor('#007DFF')
}.width('100%')
.height('100%')
}
}

