SpringBoot + MyBatis
配套前端 Vue+ECharts 可视化大屏,后端分为 3 个核心文件:启动类、Controller控制层、Mapper持久层,所有代码添加完整注释,同时讲解框架原理、执行流程、前后端对应关系。
一、整体技术体系说明
- SpringBoot:简化 Spring Web 开发,内置 Tomcat,自动配置 Web、MyBatis、JSON 序列化,快速提供 HTTP 接口给前端 axios 请求。
- MyBatis:轻量持久层框架,负责 Java 和 MySQL 交互;本项目使用注解式 SQL(
@Select),无需 XML 文件,适合快速开发大屏报表接口。 - 完整请求链路
前端Vue axios请求→ScreenController 控制器→MarketMapper MyBatis执行SQL→MySQL统计数据表→ JSON数据返回前端 ECharts 绘图
二、启动类 ScreenApp.java(完整注释版+深度解析)
/*
* 项目启动主类,SpringBoot程序入口
* 功能:1. 启动内置Tomcat服务器;2. 配置MySQL数据源;3. 配置MyBatis全局参数;4. 扫描所有Mapper接口
* 访问地址:http://localhost:8080
* @MapperScan("com.demo"):扫描指定包下的 MyBatis Mapper 接口,完成接口的实例化;
* 数据源配置(dataSource() Bean):配置 MySQL 连接信息(驱动、地址、账号密码),让应用能访问数据库;
* MyBatis 自定义配置(mybatisConfig() Bean):开启 “下划线转驼峰” 功能,解决数据库字段(下划线)与 Java 属性(驼峰)的自动映射;
* 前端请求 → ScreenController(接收请求)→ MarketMapper(执行SQL查库)→ 数据库返回数据 → MarketMapper(封装为Map/List)→ ScreenController(返回JSON)→ 前端渲染图表
*/
package com.demo; //申明文件属于哪个包
import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import javax.sql.DataSource;
/**
* @SpringBootApplication:SpringBoot核心复合注解
* 包含3个注解功能:
* 1. @Configuration:当前类是配置类,可使用@Bean注册对象到Spring容器
* 2. @EnableAutoConfiguration:自动识别项目依赖,自动配置Tomcat、MyBatis、JSON转换器等
* 3. @ComponentScan:自动扫描当前包com.demo下所有Controller、Mapper、Service交给Spring管理
*
* @MapperScan("com.demo"):MyBatis专属注解
* 扫描com.demo包下所有标记@Mapper的接口,自动生成Mapper动态代理实现类,才能在Controller中注入使用
*/
@SpringBootApplication
@MapperScan("com.demo")
public class ScreenApp {
/**
* Java程序入口方法,程序运行起点
* SpringApplication.run():启动Spring容器,初始化所有Bean,启动内置Tomcat
* @param args 启动参数
*/
public static void main(String[] args) {
SpringApplication.run(ScreenApp.class, args);
// 启动成功后,前端页面访问:http://localhost:8080/index.html
// 接口统一前缀:http://localhost:8080/api/xxx
}
/**
* @Bean:将方法返回的数据源对象注册到Spring容器,全局可被MyBatis自动引用
* DataSource:数据库连接对象,MyBatis底层依靠它连接MySQL执行SQL
* @return 简易JDBC数据源(适合本地开发演示,生产建议Druid连接池)
*/
@Bean
public DataSource dataSource() {
// 创建简易数据源对象
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName("com.mysql.cj.jdbc.Driver"); // MySQL8.x版本驱动类
// 数据库连接地址参数说明
// 127.0.0.1:3306:本地MySQL服务地址端口 test2:要连接的数据库名称
// serverTimezone=Asia/Shanghai:设置东八区,解决日期时间时区报错
// useSSL=false:本地开发关闭SSL加密,线上环境必须开启
ds.setUrl("jdbc:mysql://127.0.0.1:3306/test2?serverTimezone=Asia/Shanghai&useSSL=false");
ds.setUsername("root");
ds.setPassword("123456");
return ds;
}
/**
* 自定义MyBatis全局配置Bean
* 开启数据库下划线字段 自动映射 Java驼峰key
* 例:数据库字段 price_range → Map中key自动变为 priceRange,和前端JS字段完全匹配
*/
@Bean
public ConfigurationCustomizer mybatisConfig() {
// Lambda表达式自定义MyBatis配置
return config -> {
// 开启下划线转驼峰功能
config.setMapUnderscoreToCamelCase(true);
};
}
}
三、控制层 ScreenController.java(完整注释版+前后端对应说明)
/*
* SpringMVC控制器,接收前端axios发送的GET请求
* 职责:接收请求 → 调用Mapper查询数据库 → 将数据转为JSON返回前端
* 5个接口和前端vue_echarts.js中5次axios.get请求一一对应
* 接收前端 HTTP 请求,调用数据访问层接口,返回格式化的 JSON 数据
* 作为 Spring MVC 的控制器(@Controller),暴露多个 RESTful 接口(@GetMapping),对应前端不同可视化图表的数据需求;
* @ResponseBody将返回的 Map/List 数据自动转为 JSON 格式,供前端(如 ECharts)调用;
*/
package com.demo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
/**
* @Controller:标识当前类为MVC控制器,专门处理浏览器/前端AJAX请求 专门接收前端网页、接口的请求,交给 Spring 管理。
* 区别@RestController:@RestController = @Controller + @ResponseBody
* 本项目分开书写,方便后期新增页面跳转功能
*/
@Controller
public class ScreenController {
/**
* @Resource:依赖注入注解
* Spring自动从容器中获取MyBatis生成的MarketMapper代理对象,无需手动new
* 所有接口数据查询都依靠该对象调用Mapper中的SQL方法
*/
@Resource
private MarketMapper marketMapper;
/**
* 接口1:/api/index 大屏顶部汇总指标
* 前端对应代码:axios.get("/api/index")
* @GetMapping("/api/index"):仅接收GET请求,匹配接口路径
* @ResponseBody:将返回的Map自动序列化为JSON字符串返回前端
* @return 单个Map对象,存放市场总指标数字
*/
@ResponseBody
@GetMapping("/api/index")
public Map<String, Object> getIndex() {
// 调用Mapper查询今日市场汇总数据
return marketMapper.getIndexData();
}
/**
* 接口2:/api/pie 饼图-价格区间分布数据
* 前端对应代码:axios.get("/api/pie")
* @return List<Map> 多条数据,用于ECharts饼图渲染
*/
@ResponseBody
@GetMapping("/api/pie")
public List<Map<String, Object>> getPie() {
return marketMapper.getPieData();
}
/**
* 接口3:/api/rise 涨幅柱状图数据
* 前端对应代码:axios.get("/api/rise")
* @return 涨幅前5条商品数据
*/
@ResponseBody
@GetMapping("/api/rise")
public List<Map<String, Object>> getRiseBar() {
return marketMapper.getRiseBarData();
}
/**
* 接口4:/api/fall 跌幅柱状图数据
* 前端对应代码:axios.get("/api/fall")
* @return 跌幅前5条商品数据
*/
@ResponseBody
@GetMapping("/api/fall")
public List<Map<String, Object>> getFallBar() {
return marketMapper.getFallBarData();
}
/**
* 接口5:/api/line 15日多品类价格折线图
* 前端对应代码:axios.get("/api/line")
* @return 蔬菜、肉禽蛋、水果15天每日均价数据
*/
@ResponseBody
@GetMapping("/api/line")
public List<Map<String, Object>> getLine() {
return marketMapper.getLineData();
}
}
四、持久层 MarketMapper.java(MyBatis SQL层 全注释)
/*
* MyBatis数据库操作接口,负责编写所有查询SQL
* @Mapper:标记为MyBatis映射接口,配合启动类@MapperScan生成动态代理类
* @Select:注解式SQL,直接在方法上写查询语句,无需创建Mapper.xml文件
* 返回值 Map / List<Map>:数据库查询结果自动封装,无需自定义实体类
*/
package com.demo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
import java.util.Map;
/**
* @Mapper MyBatis核心注解
* Spring启动时,@MapperScan扫描该接口,自动生成代理实现类,底层封装JDBC操作
* 无需手动编写JDBC连接、关闭连接、结果集解析等冗余代码
*/
@Mapper
public interface MarketMapper {
/**
* 查询大屏顶部核心指标数据
* 对应接口 /api/index
* SQL逻辑:从当日指标统计表取最新一条统计数据
* order by stat_date desc limit 1:按统计日期倒序,只拿最新一天数据
* as 别名:将数据库下划线字段转为驼峰,配合MyBatis自动映射配置
* @return 单行数据Map,key为驼峰字段名,value为统计数值
*/
@Select("select total_category_cnt as totalCategoryCnt,second_category_cnt as secondCategoryCnt,market_avg_price as marketAvgPrice from ads_market_today_index order by stat_date desc limit 1")
Map<String, Object> getIndexData();
/**
* 查询饼图价格区间分布数据
* 对应接口 /api/pie
* SQL逻辑:按价格区间分组统计商品数量,按占比降序,取前6组避免饼图分区过多
* @return 多条数据List集合,每条包含价格区间、商品数量、占比
*/
@Select("select price_range as priceRange,record_count as recordCount,ratio from ads_market_price_distribution order by stat_date desc, ratio desc limit 6")
List<Map<String, Object>> getPieData();
/**
* 查询当日涨幅前5商品(绿色柱状图)
* 对应接口 /api/rise
* SQL逻辑:price_diff价格差值降序,数值越大涨幅越高,取前5条
* @return 商品名称、涨幅数值列表
*/
@Select("select prod_name as prodName,price_diff as priceDiff from ads_market_day_rise_fall order by stat_date desc , price_diff desc limit 5")
List<Map<String, Object>> getRiseBarData();
/**
* 查询当日跌幅前5商品(红色柱状图)
* 对应接口 /api/fall
* SQL逻辑:price_diff为负数,升序排序,负数越小跌幅越大,取前5条
* @return 商品名称、跌幅数值列表
*/
@Select("select prod_name as prodName,price_diff as priceDiff from ads_market_day_rise_fall order by stat_date desc , price_diff asc limit 5")
List<Map<String, Object>> getFallBarData();
/**
* 查询15日价格趋势折线数据
* 对应接口 /api/line
* SQL逻辑:查询所有品类15天每日均价,day0-day14对应前端X轴15个日期
* @return 多品类折线数据,每条记录包含品类名称+15天价格
*/
@Select("select line_name as lineName,day_0 as day0,day_1 as day1,day_2 as day2,day_3 as day3,day_4 as day4,day_5 as day5,day_6 as day6,day_7 as day7,day_8 as day8,day_9 as day9,day_10 as day10,day_11 as day11,day_12 as day12,day_13 as day13,day_14 as day14 from ads_market_trend_line order by stat_date desc")
List<Map<String, Object>> getLineData();
}
五、配套补充:完整执行流程分步注释讲解
-
项目启动流程
- 运行
ScreenApp.main(),触发@SpringBootApplication自动配置; - 执行
@Bean方法创建DataSource数据源,建立MySQL连接; @MapperScan("com.demo")扫描MarketMapper,MyBatis生成代理类存入Spring容器;- Spring扫描
ScreenController,自动注入marketMapper代理对象; - 内置Tomcat 8080端口启动,等待前端发送HTTP请求。
- 运行
-
前端请求后端完整流程(以饼图接口为例)
- Vue页面挂载完成,执行
loadAllData(),axios发送GET请求http://localhost:8080/api/pie; - SpringMVC匹配
@GetMapping("/api/pie")方法,进入getPie(); - 调用
marketMapper.getPieData(),执行@Select注解中的SQL; - MyBatis通过DataSource连接MySQL,执行查询语句;
- MySQL返回结果集,MyBatis自动将下划线字段转为驼峰,封装为
List<Map>; @ResponseBody将List转为标准JSON字符串返回浏览器;- 前端接收JSON赋值给
pieList,调用drawPie()渲染ECharts饼图。
- Vue页面挂载完成,执行
六、关键配置与前后端字段匹配说明
- MyBatis下划线转驼峰作用
数据库字段
prod_name→ Map keyprodName前端JS代码直接使用item.prodName取值,不需要手动转换字段名,前后端字段完全对齐。 - 接口一一对应对照表 | 前端axios请求地址 | 后端Controller接口方法 | Mapper查询方法 | 图表用途 | | ----------------- | ---------------------- | ---------------- | ---------------- | | /api/index | getIndex() | getIndexData() | 顶部数字指标 | | /api/pie | getPie() | getPieData() | 价格分布饼图 | | /api/rise | getRiseBar() | getRiseBarData() | 涨幅绿色柱状图 | | /api/fall | getFallBar() | getFallBarData() | 跌幅红色柱状图 | | /api/line | getLine() | getLineData() | 15日多折线趋势图 |
七、代码优缺点注释总结
现有代码优势
- 极简架构:三层结构(启动类+Controller+Mapper),无多余实体类、Service层,快速开发大屏;
- 注解开发:SQL直接写在Mapper接口,逻辑直观,方便阅读报表业务;
- 字段自动映射:MyBatis配置下划线转驼峰,前后端联调成本低;
- 接口轻量化:直接返回Map/List,无需创建VO实体,适合临时统计大屏。
代码存在缺陷(生产环境优化注释)
- 数据库连接信息硬编码在代码中,生产环境需迁移至
application.yml配置文件; DriverManagerDataSource无连接池,并发访问数据库性能差,推荐Druid连接池;- 使用Map接收数据无类型校验,容易出现字段拼写错误,正式项目建议自定义VO实体;
- 未配置跨域,本地Vue前端直接访问8080接口会报跨域错误,可在Controller添加
@CrossOrigin(origins = "*"); - 无全局异常处理器,SQL报错直接返回堆栈信息,前端无法友好提示;
- 无缓存机制,每次刷新页面重复查询数据库,高频访问会增加MySQL压力,可引入Redis缓存每日统计数据。