一、回顾
1、数据仓库
数据集成的地方,对外来数据进行清洗,分层处理,分析指标得出结论
2、外卖平台思路
MySQL(原始数据) —> (ODS层存储最接近原始数据的层,DIM层维度层一般存储一些维度数据,DW层一般又分为三层【DWS】,将之前的数据合并为一张宽表,为后面的数据统计做准备,通过HQL语句将统计的结果放入DM层) HIve干的事儿 —> MySQL数据中
3、疑问?
为什么不直接在mysql中将四个表进行关联查询呢?
1)MySQL中的数据会越来越大,每次执行的SQL速度会越来越慢,执行一个庞大的SQL语句,会拖累整个mysql服务器。
2)外卖分析平台的数据,也不仅仅来自于我们的mysql
3) 每次统计的结果下一次还要重新做统计,不能重复利用。
二、Java的环境配置(IDEA+JDK+Maven)
Jdk1.8 + IDEA2019.1 + MySQL5.7 + Maven 3.5.2
1、首先安装我们的jdk(直接一直下一步下一步,一般我喜欢将这个软件安装在C盘)
2、安装我们的 idea
3、解压maven
解压到一个没有中文路径的盘符或者文件夹下。<br />我解压到了 E:\apache-maven-3.5.2-bin\apache-maven-3.5.2<br />接着配置maven的settings.xml 配置文件,直接替换老闫的即可。 maven的conf下<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/22131196/1641695423486-2d34fce0-19f6-4c7a-b89c-ffed3f1a6bce.png#clientId=uc0150ab5-0a37-4&from=paste&height=216&id=ud286003d&margin=%5Bobject%20Object%5D&name=image.png&originHeight=216&originWidth=691&originalType=binary&ratio=1&size=19164&status=done&style=none&taskId=uc8ba8b2e-3c23-45f2-80ec-c105de1f43c&width=691)<br />老闫的settings.xml 有啥玄妙的地方?<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/22131196/1641695548942-16dc638b-6545-4b97-83f7-c8127a4563a0.png#clientId=uc0150ab5-0a37-4&from=paste&height=136&id=u37166dc9&margin=%5Bobject%20Object%5D&name=image.png&originHeight=136&originWidth=1049&originalType=binary&ratio=1&size=15428&status=done&style=none&taskId=u5a414601-1925-4e6d-9b55-c5bdd7d7156&width=1049)<br />第二个地方:<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/22131196/1641695630035-ad2b8888-f2b3-4f53-aef2-3e63301b42f8.png#clientId=uc0150ab5-0a37-4&from=paste&height=278&id=uf5e02976&margin=%5Bobject%20Object%5D&name=image.png&originHeight=278&originWidth=1163&originalType=binary&ratio=1&size=33607&status=done&style=none&taskId=u1bc7eb00-782c-4229-af80-3845ee28c82&width=1163)<br />Maven到底是干嘛的? ----> Maven是帮我们下载需要的jar包。
4、IDEA和Maven进行绑定
5、idea关联我们本地的jdk
三、开始搞开发(SpringBoot+Mybatis+Echarts)
1、创建项目(SpringBoot项目)
说明项目名字不能用大写。
选择需要的jar包:
一路创建,创建成功后,会进入项目,右下角有滚动的进度条,是在帮助我们下载需要的jar包,等它下载完不动了即可。
每当你的下载的进度卡到一个点过不去,可以关掉idea,然后重新进入,重新进入之后,选择右侧的maven,点击刷新按钮
我删除了一个插件:在pom.xml 中。
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
2、编写代码第一式—springboot
编写代码:
package com.yxh.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class OrderShowController {
@RequestMapping("/hello")
public String hello(){
// sout 直接回车就出现打印的语句
System.out.println("Hello SpringBoot!!!!");
return "Hello SpringBoot";
}
}
启动项目测试是否成功!
启动报错:原因是导入了mysql的相关的jar包,却没有指定数据库连接地址,所以报错!!!!!
在resources 文件夹的配置文件中 application.properties中,编写数据库连接数据
spring.datasource.url=jdbc:mysql://192.168.32.135:3306/el_report
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root
3、编写java代码第二式—学习一个Echarts
网址:https://echarts.apache.org/zh/index.html
是由百度公司推出的非常有名的一个图形化的报表工具。
入门案例:
折线图:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<!-- 引入刚刚下载的 ECharts 文件 -->
<script src="echarts.min.js"></script>
</head>
<body>
<!-- 为 ECharts 准备一个定义了宽高的 DOM -->
<div id="main" style="width: 600px;height:400px;"></div>
<script type="text/javascript">
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('main'));
// 指定图表的配置项和数据
var option = {
title: {
text: 'ECharts 入门示例'
},
tooltip: {},
legend: {
data: ['销量']
},
xAxis: {
data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
},
yAxis: {},
series: [
{
name: '销量',
type: 'bar',
data: [5, 20, 36, 10, 10, 20]
}
]
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
</script>
</body>
</html>
饼状图:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<!-- 引入刚刚下载的 ECharts 文件 -->
<script src="echarts.min.js"></script>
</head>
<body>
<!-- 为 ECharts 准备一个定义了宽高的 DOM -->
<div id="main" style="width: 600px;height:400px;"></div>
<script type="text/javascript">
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('main'));
// 指定图表的配置项和数据
var option = {
series: [
{
type: 'pie',
data: [
{
value: 335,
name: '直接访问'
},
{
value: 234,
name: '联盟广告'
},
{
value: 1548,
name: '搜索引擎'
}
],
radius: '50%'
}
]
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
</script>
</body>
</html>
一般的图形,我们只需要替换option这一部分即可,找到合适的图标,修改上面的文字和数据即可变为你自己的图标。
项目中的页面:
重新启动你的java项目:
如果你的页面粘贴进去之后,重启发现访问不了页面,不是跨域的问题,而是页面没有编译,需要先清理一下编译的内容,然后重启即可。
什么是跨域?就是两个项目,域名不同,但是需要通信,这个时候叫跨域。
4、编写代码
统计的是订单在家里,公司以及学校的情况。
1)编写一个mapper ,用于查询数据,将查询的结果存放在一个实体中。
创建了一个mapper 包,存放mapper里面的接口
package com.yxh.mapper;
import com.yxh.entry.OrderLocatHourDist;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
/**
* 此接口,是用来查询数据库的
*/
@Mapper
public interface OrderMapper {
@Select("select * from order_locat_hour_dist")
public OrderLocatHourDist selectOrderLocalHour();
}
2)在Controller 中,将数据封装成我们页面需要的数据格式
@Autowired
OrderMapper orderMapper;
/**
* 出结果了,但是我们的页面需要的是这样类型的数据
* {data:[100,234,345]}
*
* alt + enter 导入某个包
* @return
*/
@RequestMapping("/listOrders")
public Map<String,List<Integer>> listOrders(){
/*
在此处查询数据库,然后将结果返回给页面
*/
OrderLocatHourDist orderLocatHourDist = orderMapper.selectOrderLocalHour();
ArrayList<Integer> list = new ArrayList<>();
list.add(orderLocatHourDist.getSchool_orders());
list.add(orderLocatHourDist.getCompany_orders());
list.add(orderLocatHourDist.getHome_orders());
Map<String, List<Integer>> map = new HashMap<>();
map.put("data",list);
return map;
}
需要有一个实体,接收我们从数据库查询数据
package com.yxh.entry;
public class OrderLocatHourDist {
private String dt;
private int school_orders;
private int company_orders;
private int home_orders;
private int orders_0_5;
private int orders_6_12;
private int orders_13_15;
private int orders_16_20;
private int orders_21_24;
public String getDt() {
return dt;
}
public void setDt(String dt) {
this.dt = dt;
}
public int getSchool_orders() {
return school_orders;
}
public void setSchool_orders(int school_orders) {
this.school_orders = school_orders;
}
public int getCompany_orders() {
return company_orders;
}
public void setCompany_orders(int company_orders) {
this.company_orders = company_orders;
}
public int getHome_orders() {
return home_orders;
}
public void setHome_orders(int home_orders) {
this.home_orders = home_orders;
}
public int getOrders_0_5() {
return orders_0_5;
}
public void setOrders_0_5(int orders_0_5) {
this.orders_0_5 = orders_0_5;
}
public int getOrders_6_12() {
return orders_6_12;
}
public void setOrders_6_12(int orders_6_12) {
this.orders_6_12 = orders_6_12;
}
public int getOrders_13_15() {
return orders_13_15;
}
public void setOrders_13_15(int orders_13_15) {
this.orders_13_15 = orders_13_15;
}
public int getOrders_16_20() {
return orders_16_20;
}
public void setOrders_16_20(int orders_16_20) {
this.orders_16_20 = orders_16_20;
}
public int getOrders_21_24() {
return orders_21_24;
}
public void setOrders_21_24(int orders_21_24) {
this.orders_21_24 = orders_21_24;
}
}
页面的请求也做了一个修改:
显示效果:
第二个指标:
@RequestMapping("/listTimeOrders")
public Map<String,List<Map<String,String>>> listTimeOrders(){
OrderLocatHourDist orderLocatHourDist = orderMapper.selectOrderLocalHour();
HashMap<String, String> map1 = new HashMap<>();
HashMap<String, String> map2 = new HashMap<>();
HashMap<String, String> map3 = new HashMap<>();
HashMap<String, String> map4 = new HashMap<>();
HashMap<String, String> map5 = new HashMap<>();
map1.put("name","0~5点");
map1.put("value",orderLocatHourDist.getOrders_0_5()+"");
map2.put("name","6~12点");
map2.put("value",orderLocatHourDist.getOrders_6_12()+"");
map3.put("name","13~15点");
map3.put("value",orderLocatHourDist.getOrders_13_15()+"");
map4.put("name","16~20点");
map4.put("value",orderLocatHourDist.getOrders_16_20()+"");
map5.put("name","21~23点");
map5.put("value",orderLocatHourDist.getOrders_21_24()+"");
ArrayList<Map<String, String>> list = new ArrayList<>();
list.add(map1);
list.add(map2);
list.add(map3);
list.add(map4);
list.add(map5);
HashMap<String, List<Map<String, String>>> hashMap = new HashMap<>();
hashMap.put("data",list);
return hashMap;
}
第三个指标:
package com.yxh.mapper;
import com.yxh.entry.OrderAgeDistribute;
import com.yxh.entry.OrderLocatHourDist;
import com.yxh.entry.OrderMapDistribute;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* 此接口,是用来查询数据库的
*/
@Mapper
public interface OrderMapper {
@Select("select * from order_locat_hour_dist")
OrderLocatHourDist selectOrderLocalHour();
@Select("select * from order_paytype_age_dist")
OrderAgeDistribute selectOrderPayTypeAge();
@Select("select * from order_map_dist")
List<OrderMapDistribute> selectOrderMapDist();
}
响应的数据:
@RequestMapping("/listAgeOrders")
public Map<String, List<Double>> listAgeOrders(){
OrderAgeDistribute orderAgeDistribute = orderMapper.selectOrderPayTypeAge();
ArrayList<Double> list = new ArrayList<>();
list.add(orderAgeDistribute.getOrders_price_0_16());
list.add(orderAgeDistribute.getOrders_price_17_25());
list.add(orderAgeDistribute.getOrders_price_26_35());
list.add(orderAgeDistribute.getOrders_price_36_60());
list.add(orderAgeDistribute.getOrders_price_61_80());
list.add(orderAgeDistribute.getOrders_price_81_pluss());
Map<String, List<Double>> map = new HashMap<>();
map.put("data",list);
return map;
}
第四个Map:
页面展示
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
<title></title>
<!-- Bootstrap Styles-->
<link href="assets/css/bootstrap.css" rel="stylesheet" />
<!-- FontAwesome Styles-->
<link href="assets/css/font-awesome.css" rel="stylesheet" />
<!-- Custom Styles-->
<link href="assets/css/custom-styles.css" rel="stylesheet" />
<!-- Google Fonts-->
<link href='https://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css' />
<script src="assets/js/echarts.min.js"></script>
<script src="assets/js/china.js"></script>
<script src="assets/js/jquery-3.3.1.min.js"></script>
<style>
*{margin:0;padding:0}
html,body{
width:100%;
height:100%;
}
#main{
width:600px;
height:450px;
margin: 150px auto;
border:1px solid #ddd;
}
/*默认长宽比0.75*/
</style>
</head>
<body>
<div id="wrapper">
<nav class="navbar navbar-default top-navbar" role="navigation">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".sidebar-collapse">
<span class="sr-only">好程序员</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="index.html"><i class="fa fa-gear"></i> <strong>好程序员</strong></a>
</div>
</nav>
<!--/. NAV TOP -->
<nav class="navbar-default navbar-side" role="navigation">
<div class="sidebar-collapse">
<ul class="nav" id="main-menu">
<li>
<a href="index.html">
<i class="fa fa-dashboard"></i> 网站订单分析</a>
</li>
<li>
<a href="chart.html" >
<i class="fa fa-bar-chart-o"></i> 网站用户分析</a>
</li>
<li>
<a href="map.html" class="active-menu">
<i class="fa fa-qrcode"></i>地域分析 </a>
</li>
</ul>
</div>
</nav>
<div id="page-wrapper">
<div id="page-inner">
</div>
</div>
<!--订单分布地图==========-->
<script type="text/javascript">
var dataList=[
{name:"南海诸岛",value:0},
{name: '北京', value: randomValue()},
{name: '天津', value: randomValue()},
{name: '上海', value: randomValue()}
]
var myChart = echarts.init(document.getElementById('page-inner'));
function randomValue() {
return Math.round(Math.random()*1000);
}
option = {
tooltip: {
formatter:function(params,ticket, callback){
return params.seriesName+'<br />'+params.name+':'+params.value
}//数据格式化
},
visualMap: {
min: 0,
max: 50,
left: 'left',
top: 'bottom',
text: ['高','低'],//取值范围的文字
inRange: {
color: ['#e0ffff', '#dd1d17']//取值范围的颜色
},
show:true//图注
},
geo: {
map: 'china',
roam: false,//不开启缩放和平移
zoom:1.23,//视角缩放比例
label: {
normal: {
show: true,
fontSize:'10',
color: 'rgba(0,0,0,0.7)'
}
},
itemStyle: {
normal:{
borderColor: 'rgba(0, 0, 0, 0.2)'
},
emphasis:{
areaColor: '#4df335',//鼠标选择区域颜色
shadowOffsetX: 0,
shadowOffsetY: 0,
shadowBlur: 20,
borderWidth: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
},
series : [
{
name: '订单量',
type: 'map',
geoIndex: 0,
data:[]
}
]
};
var url='/mapOrders'
// 异步加载json格式数据
$.getJSON(url,function(data){
myChart.setOption({
/*xAxis: {
data: data.categories
},*/
series: [{
// 根据名字对应到相应的系列
//name: '订单数',
data: data.data
}]
});
});
myChart.setOption(option);
myChart.on('click', function (params) {
alert(params.name);
});
/* setTimeout(function () {
myChart.setOption({
series : [
{
name: '信息量',
type: 'map',
geoIndex: 0,
data:dataList
}
]
});
},1000)*/
</script>
</body>
初始化地图:
//首先需要对地图进行初始化
/**
* 初始化map
* @return
*/
public static List<Map<String,String>> initMap(){
List<Map<String,String>> maps = new ArrayList<>();
String[] arr = {"北京","天津","上海","重庆","河北","山西","辽宁","吉林","黑龙江",
"江苏","浙江","安徽","福建","江西","山东","河南","湖北","湖南","广东",
"海南","四川","贵州","云南","陕西","甘肃","青海","台湾","内蒙古","广西",
"西藏","宁夏","新疆","香港","澳门"};
for (int i=0;i < 34;i++){
Map<String,String> map = new HashMap<>();
map.put("name",arr[i]);
map.put("value","0");
maps.add(map);
}
return maps;
}
地图上的数据展示:
@RequestMapping("/mapOrders")
public Map<String, List<Map<String,String>>> mapOrders(){
List<OrderMapDistribute> mapDistribute = orderMapper.selectOrderMapDist();
List<Map<String,String>> res1 =initMap();
// 外面一层是初始化的数据
for (Map<String,String> m : res1){
// 数据库中的数据
for(OrderMapDistribute om : mapDistribute){
String province = om.getProvince();
if(province.contains("省")){
province = province.replace("省", "");
}else if(province.contains("市")){
province = province.replace("市", "");
}else if(province.contains("内蒙古")){
province = province.substring(0,3);
}else if(province.contains("自治区")){
province = province.substring(0,2);
}else if(province.contains("特别行政区")){
province = province.substring(0,2);
}
//判断
if(province.equals(m.get("name"))){
m.put("value",om.order_cnt+"");
break;
}
}
}
Map<String, List<Map<String,String>>> map = new HashMap<>();
map.put("data",res1);
return map;
}
还有两个实体,详见代码。
效果图: