初始化项目

This commit is contained in:
wangran
2026-01-09 11:32:52 +08:00
commit e3f3cdd336
39 changed files with 1929 additions and 0 deletions

38
.gitignore vendored Normal file
View File

@@ -0,0 +1,38 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

8
.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,8 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

7
.idea/encodings.xml generated Normal file
View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
</component>
</project>

14
.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

74
pom.xml Normal file
View File

@@ -0,0 +1,74 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bigdata</groupId>
<artifactId>SpringPhoenix</artifactId>
<packaging>war</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.0</version>
</parent>
<dependencies>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- JSTL 标签库 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<!-- 用于编译 JSP 文件 -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<!-- Phoenix 客户端依赖 -->
<dependency>
<groupId>org.apache.phoenix</groupId>
<artifactId>phoenix-client-hbase-2.4</artifactId>
<version>5.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.8.4</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,13 @@
package com.bigdata;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@MapperScan("com.bigdata.dao")
@SpringBootApplication
public class SpringbootPhoenixApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootPhoenixApplication.class,args);
}
}

View File

@@ -0,0 +1,54 @@
package com.bigdata.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* CORS 跨域配置
*/
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
// 允许的源(前端地址)
.allowedOrigins("http://localhost:5173")
// 允许的 HTTP 方法
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
// 允许的请求头
.allowedHeaders("*")
// 允许发送凭证(如 cookies
.allowCredentials(true)
// 预检请求的缓存时间(秒)
.maxAge(3600);
}
/**
* 使用 CorsFilter 作为备选方案,确保 OPTIONS 预检请求也能正确处理
*/
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
// 允许的源
config.addAllowedOrigin("http://localhost:5173");
// 允许所有 HTTP 方法
config.addAllowedMethod("*");
// 允许所有请求头
config.addAllowedHeader("*");
// 允许发送凭证
config.setAllowCredentials(true);
// 预检请求的缓存时间
config.setMaxAge(3600L);
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}

View File

@@ -0,0 +1,34 @@
package com.bigdata.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.Properties;
/**
* 数据源配置类
* 配置 Druid 数据源以支持 Phoenix 连接
*/
@Configuration
public class DataSourceConfig {
/**
* 配置 Druid 数据源
* Phoenix 连接不需要额外的属性配置,端口号在 URL 中指定
*/
@Bean
@Primary
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource druidDataSource() throws SQLException {
DruidDataSource dataSource = new DruidDataSource();
// Phoenix 连接不需要额外的属性配置
// URL 格式jdbc:phoenix:host1,host2,host3:port
// 端口号在 URL 中指定,不需要在 Properties 中配置
return dataSource;
}
}

View File

@@ -0,0 +1,69 @@
package com.bigdata.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
/**
* Phoenix 配置类
*/
@Configuration
public class PhoenixConfig {
/**
* Phoenix JDBC URL
* 格式jdbc:phoenix:host1:port1,host2:port2,host3:port3
* 或者jdbc:phoenix:host1,host2,host3:port (如果端口相同)
*/
@Value("${spring.datasource.url:jdbc:phoenix:hadoop102:2181,hadoop103:2181,hadoop104:2181}")
private String phoenixUrl;
/**
* Zookeeper 连接超时时间(毫秒)
*/
@Value("${phoenix.zookeeper.session.timeout:90000}")
private int sessionTimeout;
/**
* Zookeeper 重试次数
*/
@Value("${phoenix.zookeeper.retries:30}")
private int retries;
/**
* Zookeeper 重试间隔(毫秒)
*/
@Value("${phoenix.zookeeper.retry.interval:1000}")
private int retryInterval;
public String getPhoenixUrl() {
return phoenixUrl;
}
public void setPhoenixUrl(String phoenixUrl) {
this.phoenixUrl = phoenixUrl;
}
public int getSessionTimeout() {
return sessionTimeout;
}
public void setSessionTimeout(int sessionTimeout) {
this.sessionTimeout = sessionTimeout;
}
public int getRetries() {
return retries;
}
public void setRetries(int retries) {
this.retries = retries;
}
public int getRetryInterval() {
return retryInterval;
}
public void setRetryInterval(int retryInterval) {
this.retryInterval = retryInterval;
}
}

View File

@@ -0,0 +1,104 @@
package com.bigdata.controller;
import com.bigdata.dto.ConnectionRateQueryRequest;
import com.bigdata.dto.DataConnectionQueryRequest;
import com.bigdata.dto.OperatorConnectionRateDTO;
import com.bigdata.entity.DataConnection;
import com.bigdata.service.DataConnectionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 访问 Phoenix 中 DATACONNECTION 表的接口
*/
@RestController
public class DataConnectionController {
@Autowired
private DataConnectionService dataConnectionService;
/**
* 查询数据,支持按运营商和日期筛选
* @param request 查询请求参数,包含 operator运营商和 date日期字段均为可选
* @return 数据列表
*/
@PostMapping("/dataConnection")
public List<DataConnection> query(@RequestBody(required = false) DataConnectionQueryRequest request) {
// 如果请求体为空,创建默认请求对象
if (request == null) {
request = new DataConnectionQueryRequest();
}
String operator = null;
String date = null;
if (request.getOperator() != null && !request.getOperator().trim().isEmpty()) {
operator = request.getOperator().trim().toUpperCase();
}
if (request.getDate() != null && !request.getDate().trim().isEmpty()) {
date = request.getDate().trim();
}
// 按条件查询
List<DataConnection> list = dataConnectionService.getByCondition(operator, date);
// 打印到控制台
System.out.println("====== data_connection query ======");
System.out.println("Operator: " + (operator != null ? operator : "ALL"));
System.out.println("Date: " + (date != null ? date : "ALL"));
System.out.println("Total records: " + list.size());
for (DataConnection dc : list) {
System.out.println(dc);
}
System.out.println("================================================");
return list;
}
/**
* 统计各运营商的连接率,支持时间范围查询
* @param request 查询请求参数,包含 startDate开始日期和 endDate结束日期字段均为可选
* @return 运营商连接率统计列表,包含运营商名称和连接率百分比
*/
@PostMapping("/dataConnection/connectionRate")
public List<OperatorConnectionRateDTO> getConnectionRate(@RequestBody(required = false) ConnectionRateQueryRequest request) {
// 如果请求体为空,创建默认请求对象
if (request == null) {
request = new ConnectionRateQueryRequest();
}
String startDate = null;
String endDate = null;
if (request.getStartDate() != null && !request.getStartDate().trim().isEmpty()) {
startDate = request.getStartDate().trim();
}
if (request.getEndDate() != null && !request.getEndDate().trim().isEmpty()) {
endDate = request.getEndDate().trim();
}
// 按条件查询连接率
List<OperatorConnectionRateDTO> result = dataConnectionService.getOperatorConnectionRate(startDate, endDate);
// 打印到控制台
System.out.println("====== operator connection rate statistics ======");
System.out.println("Start Date: " + (startDate != null ? startDate : "ALL"));
System.out.println("End Date: " + (endDate != null ? endDate : "ALL"));
for (OperatorConnectionRateDTO dto : result) {
System.out.println("Operator: " + dto.getOperator() +
", Total: " + dto.getTotalCount() +
", Success: " + dto.getSuccessCount() +
", Rate: " + dto.getConnectionRate() + "%");
}
System.out.println("================================================");
return result;
}
}

View File

@@ -0,0 +1,33 @@
package com.bigdata.controller;
import com.bigdata.entity.Order;
import com.bigdata.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.ArrayList;
import java.util.List;
@Controller
public class OrderController {
@Autowired
private OrderService orderService;
@RequestMapping("/getOrders")
public String getOrdersList(Model model){
List<Order> list = this.orderService.getOrders();
List<Long> ids=new ArrayList<>();
List<Long> totalAmounts=new ArrayList<>();
for(Order order:list){
ids.add(order.getId());
totalAmounts.add(order.getTotalAmount());
}
model.addAttribute("ids",ids);
model.addAttribute("totalAmounts",totalAmounts);
return "orders";
}
}

View File

@@ -0,0 +1,42 @@
package com.bigdata.controller;
import com.bigdata.util.PhoenixConnectionDiagnostic;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* Phoenix 连接诊断控制器
*/
@RestController
@RequestMapping("/phoenix/diagnostic")
public class PhoenixDiagnosticController {
/**
* 测试连接
* @param url Phoenix JDBC URL可选如果不提供则使用默认 URL
* @return 测试结果
*/
@GetMapping("/test")
public PhoenixConnectionDiagnostic.ConnectionTestResult testConnection(
@RequestParam(required = false) String url) {
if (url == null || url.isEmpty()) {
// 使用默认 URL格式jdbc:phoenix:host1,host2,host3:port/schema
// schema 指定要使用的数据库(库名),这里使用 telecom
url = "jdbc:phoenix:hadoop102,hadoop103,hadoop104:2181/telecom";
}
return PhoenixConnectionDiagnostic.testConnection(url);
}
/**
* 测试多个连接 URL
* @param urls 多个 URL用逗号分隔
* @return 测试结果列表
*/
@PostMapping("/test-multiple")
public List<PhoenixConnectionDiagnostic.ConnectionTestResult> testConnections(
@RequestParam String urls) {
String[] urlArray = urls.split(",");
return PhoenixConnectionDiagnostic.testConnections(urlArray);
}
}

View File

@@ -0,0 +1,49 @@
package com.bigdata.controller;
import com.bigdata.service.PhoenixQueryService;
import com.bigdata.util.PhoenixQueryUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
/**
* Phoenix 查询控制器
*/
@RestController
@RequestMapping("/phoenix")
public class PhoenixQueryController {
@Autowired
private PhoenixQueryService phoenixQueryService;
/**
* 查询订单列表
* @return 订单列表
*/
@GetMapping("/orders")
public List<PhoenixQueryUtil.OrderResult> getOrders() {
return phoenixQueryService.queryOrders();
}
/**
* 执行自定义 SQL 查询
* @param sql SQL 查询语句
* @return 查询结果
*/
@PostMapping("/query")
public List<Map<String, Object>> executeQuery(@RequestParam String sql) {
return phoenixQueryService.executeCustomQuery(sql);
}
/**
* 使用 GET 方式执行查询(用于简单查询)
* @param sql SQL 查询语句
* @return 查询结果
*/
@GetMapping("/query")
public List<Map<String, Object>> executeQueryGet(@RequestParam String sql) {
return phoenixQueryService.executeCustomQuery(sql);
}
}

View File

@@ -0,0 +1,48 @@
package com.bigdata.dao;
import com.bigdata.dto.OperatorConnectionRateDTO;
import com.bigdata.entity.DataConnection;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface DataConnectionMapper {
/**
* 查询所有网络连接数据
*/
List<DataConnection> selectAll();
/**
* 按运营商查询网络连接数据
* @param operator 运营商名称CMCC、CUCC、CTCC
*/
List<DataConnection> selectByOperator(@Param("operator") String operator);
/**
* 按条件查询网络连接数据(支持运营商和日期)
* @param operator 运营商名称CMCC、CUCC、CTCC可选
* @param date 查询日期yyyy-MM-dd可选
*/
List<DataConnection> selectByCondition(@Param("operator") String operator, @Param("date") String date);
/**
* 统计各运营商的连接率(支持时间范围)
* @param startDate 开始日期yyyy-MM-dd可选
* @param endDate 结束日期yyyy-MM-dd可选
* @return 运营商连接率统计列表
*/
List<OperatorConnectionRateDTO> selectOperatorConnectionRateByDateRange(@Param("startDate") String startDate, @Param("endDate") String endDate);
/**
* 统计各运营商的连接率(无时间范围)
* @return 运营商连接率统计列表
*/
List<OperatorConnectionRateDTO> selectOperatorConnectionRate();
/**
* 查询最新的 10 条网络连接数据
*/
List<DataConnection> selectLatest10();
}

View File

@@ -0,0 +1,31 @@
package com.bigdata.dao;
import com.bigdata.dto.RegionStatisticsDTO;
import com.bigdata.entity.NWQuality;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface NWQualityMapper {
/**
* 按条件查询网络质量数据(支持运营商和时间范围)
* @param operator 运营商名称(电信、移动、联通、铁通),可选
* @param startDate 开始日期yyyy-MM-dd可选
* @param endDate 结束日期yyyy-MM-dd可选
*/
List<NWQuality> selectByCondition(@Param("operator") String operator,
@Param("startDate") String startDate,
@Param("endDate") String endDate);
/**
* 统计各地区数量(支持运营商和时间范围筛选)
* @param operator 运营商名称(电信、移动、联通、铁通),可选
* @param startDate 开始日期yyyy-MM-dd可选
* @param endDate 结束日期yyyy-MM-dd可选
* @return 地区统计列表
*/
List<RegionStatisticsDTO> selectRegionStatistics(@Param("operator") String operator,
@Param("startDate") String startDate,
@Param("endDate") String endDate);
}

View File

@@ -0,0 +1,8 @@
package com.bigdata.dao;
import com.bigdata.entity.Order;
import java.util.List;
public interface OrderMapper {
List<Order> getOrders();
}

View File

@@ -0,0 +1,20 @@
package com.bigdata.dto;
import lombok.Data;
/**
* 连接率统计查询请求参数
*/
@Data
public class ConnectionRateQueryRequest {
/**
* 开始日期格式yyyy-MM-dd可选
*/
private String startDate;
/**
* 结束日期格式yyyy-MM-dd可选
*/
private String endDate;
}

View File

@@ -0,0 +1,20 @@
package com.bigdata.dto;
import lombok.Data;
/**
* DataConnection 查询请求参数
*/
@Data
public class DataConnectionQueryRequest {
/**
* 运营商名称CMCC、CUCC、CTCC可选
*/
private String operator;
/**
* 查询日期格式yyyy-MM-dd可选
*/
private String date;
}

View File

@@ -0,0 +1,25 @@
package com.bigdata.dto;
import lombok.Data;
/**
* NWQuality 查询请求参数
*/
@Data
public class NWQualityQueryRequest {
/**
* 运营商名称(电信、移动、联通、铁通),可选
*/
private String operator;
/**
* 开始日期格式yyyy-MM-dd可选
*/
private String startDate;
/**
* 结束日期格式yyyy-MM-dd可选
*/
private String endDate;
}

View File

@@ -0,0 +1,34 @@
package com.bigdata.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 运营商连接率统计 DTO
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class OperatorConnectionRateDTO {
/**
* 运营商名称CMCC、CUCC、CTCC
*/
private String operator;
/**
* 连接率百分比
*/
private Double connectionRate;
/**
* 总记录数
*/
private Long totalCount;
/**
* 连接成功数
*/
private Long successCount;
}

View File

@@ -0,0 +1,29 @@
package com.bigdata.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 地区统计 DTO
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class RegionStatisticsDTO {
/**
* 地区名称(省份+城市)
*/
private String region;
/**
* 运营商名称
*/
private String operator;
/**
* 记录数量
*/
private Long count;
}

View File

@@ -0,0 +1,37 @@
package com.bigdata.entity;
import lombok.Data;
/**
* 对应 Phoenix 表 DATACONNECTION
*/
@Data
public class DataConnection {
private Integer id;
private String imei;
private String networkType;
private String wifiBssid;
private String wifiState;
private String wifiRssi;
private String mobileState;
private String mobileNetworkType;
private String networkId;
private String gsmStrength;
private String cdmaDbm;
private String evdoDbm;
private String internalIp;
private String webUrl;
private String pingValue;
private String userLat;
private String userLon;
private String userLocationInfo;
private String bsLat;
private String bsLon;
private String timeIndexClient;
private String version;
private String timeServerInsert;
private String ds;
private String dt;
}

View File

@@ -0,0 +1,23 @@
package com.bigdata.entity;
import lombok.Data;
/**
* 对应 Phoenix 表 NWQUALITY
*/
@Data
public class NWQuality {
private Long id;
private String gpsLat;
private String gpsLon;
private String nwOperator;
private Double ulSpeed;
private Double dlSpeed;
private Double latency;
private String province;
private Long daytime;
private String nwType;
private String landmark;
private String companyModel;
}

View File

@@ -0,0 +1,39 @@
package com.bigdata.entity;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.ToString;
import java.util.Date;
@Data
public class Order {
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getTotalAmount() {
return totalAmount;
}
public void setTotalAmount(Long totalAmount) {
this.totalAmount = totalAmount;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
private Long id;
private Long totalAmount;
private Date createTime;
}

View File

@@ -0,0 +1,38 @@
package com.bigdata.example;
import java.sql.*;
import java.util.Properties;
/**
* Phoenix 客户端示例
* 完全按照标准 JDBC 代码格式
*/
public class PhoenixClient {
public static void main(String[] args) throws SQLException {
// 标准的 JDBC 代码
// 1. 添加链接(指定使用 telecom 库)
String url = "jdbc:phoenix:hadoop102,hadoop103,hadoop104:2181/telecom";
// 2. 创建配置
// 没有需要添加的必要配置,因为 Phoenix 没有账号密码
Properties properties = new Properties();
// 3. 获取连接
Connection connection = DriverManager.getConnection(url, properties);
// 4. 编译 SQL 语句
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM TB_ORDER");
// 5. 执行语句
ResultSet resultSet = preparedStatement.executeQuery();
// 6. 输出结果
while (resultSet.next()) {
System.out.println("ID: " + resultSet.getLong("ID") +
", TotalAmount: " + resultSet.getLong("TOTAL_AMOUNT") +
", CreateTime: " + resultSet.getTimestamp("CREATE_TIME"));
}
// 7. 关闭资源
resultSet.close();
preparedStatement.close();
connection.close();
}
}

View File

@@ -0,0 +1,99 @@
package com.bigdata.example;
import com.bigdata.util.PhoenixQueryUtil;
import java.sql.*;
import java.util.List;
import java.util.Properties;
/**
* Phoenix JDBC 查询使用示例
*/
public class PhoenixQueryExample {
public static void main(String[] args) {
// 示例 1: 使用工具类查询订单
example1_UseUtilClass();
// 示例 2: 直接使用 JDBC 连接查询
example2_DirectJDBC();
}
/**
* 示例 1: 使用工具类查询
*/
public static void example1_UseUtilClass() {
System.out.println("=== 示例 1: 使用工具类查询订单 ===");
try {
List<PhoenixQueryUtil.OrderResult> orders = PhoenixQueryUtil.queryOrders();
for (PhoenixQueryUtil.OrderResult order : orders) {
System.out.println(order);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 示例 2: 直接使用 JDBC 连接查询
*/
public static void example2_DirectJDBC() {
System.out.println("\n=== 示例 2: 直接使用 JDBC 连接查询 ===");
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
// 标准的 JDBC 代码
// 1. 连接 URL指定使用 telecom 库)
// Phoenix JDBC URL 格式jdbc:phoenix:host1,host2,host3:port/schema
// 注意:端口号在最后一个主机后面,表示所有主机共用同一个端口
// schema 指定要使用的数据库(库名),这里使用 telecom
// 如果主机名连接不上,可以尝试使用 IP 地址
String url = "jdbc:phoenix:hadoop102,hadoop103,hadoop104:2181/telecom";
// 或者使用 IP 地址:
// String url = "jdbc:phoenix:192.168.10.102,192.168.10.103,192.168.10.104:2181/telecom";
// 2. 创建配置
// 没有需要添加的必要配置,因为 Phoenix 没有账号密码
Properties properties = new Properties();
// 3. 获取连接
connection = DriverManager.getConnection(url, properties);
// 4. 创建 Statement
statement = connection.createStatement();
// 5. 执行查询
String sql = "SELECT * FROM TB_ORDER";
resultSet = statement.executeQuery(sql);
// 6. 处理结果集
System.out.println("查询结果:");
while (resultSet.next()) {
Long id = resultSet.getLong("ID");
Long totalAmount = resultSet.getLong("TOTAL_AMOUNT");
Timestamp createTime = resultSet.getTimestamp("CREATE_TIME");
System.out.println("ID: " + id + ", TotalAmount: " + totalAmount + ", CreateTime: " + createTime);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 7. 关闭资源
try {
if (resultSet != null) {
resultSet.close();
}
if (statement != null) {
statement.close();
}
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}

View File

@@ -0,0 +1,46 @@
package com.bigdata.service;
import com.bigdata.entity.DataConnection;
import java.util.List;
public interface DataConnectionService {
/**
* 查询所有数据
*/
List<DataConnection> getAll();
/**
* 按运营商查询数据
* @param operator 运营商名称CMCC、CUCC、CTCC
*/
List<DataConnection> getByOperator(String operator);
/**
* 按条件查询数据(支持运营商和日期)
* @param operator 运营商名称CMCC、CUCC、CTCC可选
* @param date 查询日期yyyy-MM-dd可选
*/
List<DataConnection> getByCondition(String operator, String date);
/**
* 统计各运营商的连接率(支持时间范围)
* @param startDate 开始日期yyyy-MM-dd可选
* @param endDate 结束日期yyyy-MM-dd可选
* @return 运营商连接率统计列表
*/
List<com.bigdata.dto.OperatorConnectionRateDTO> getOperatorConnectionRate(String startDate, String endDate);
/**
* 统计各运营商的连接率(无时间范围)
* @return 运营商连接率统计列表
*/
List<com.bigdata.dto.OperatorConnectionRateDTO> getOperatorConnectionRate();
/**
* 查询最新的 10 条数据
*/
List<DataConnection> getLatest10();
}

View File

@@ -0,0 +1,27 @@
package com.bigdata.service;
import com.bigdata.dto.RegionStatisticsDTO;
import com.bigdata.entity.NWQuality;
import java.util.List;
public interface NWQualityService {
/**
* 按条件查询网络质量数据(支持运营商和时间范围)
* @param operator 运营商名称(电信、移动、联通、铁通),可选
* @param startDate 开始日期yyyy-MM-dd可选
* @param endDate 结束日期yyyy-MM-dd可选
* @return 网络质量数据列表
*/
List<NWQuality> getByCondition(String operator, String startDate, String endDate);
/**
* 统计各地区数量(支持运营商和时间范围筛选)
* @param operator 运营商名称(电信、移动、联通、铁通),可选
* @param startDate 开始日期yyyy-MM-dd可选
* @param endDate 结束日期yyyy-MM-dd可选
* @return 地区统计列表
*/
List<RegionStatisticsDTO> getRegionStatistics(String operator, String startDate, String endDate);
}

View File

@@ -0,0 +1,9 @@
package com.bigdata.service;
import com.bigdata.entity.Order;
import java.util.List;
public interface OrderService {
List<Order> getOrders();
}

View File

@@ -0,0 +1,29 @@
package com.bigdata.service;
import com.bigdata.util.PhoenixQueryUtil;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Phoenix 查询服务接口
*/
public interface PhoenixQueryService {
/**
* 查询订单列表
* @return 订单列表
*/
List<PhoenixQueryUtil.OrderResult> queryOrders();
/**
* 执行自定义 SQL 查询
* @param sql SQL 语句
* @return 查询结果列表
*/
List<Map<String, Object>> executeCustomQuery(String sql);
}

View File

@@ -0,0 +1,48 @@
package com.bigdata.service.impl;
import com.bigdata.dao.DataConnectionMapper;
import com.bigdata.dto.OperatorConnectionRateDTO;
import com.bigdata.entity.DataConnection;
import com.bigdata.service.DataConnectionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class DataConnectionServiceImpl implements DataConnectionService {
@Autowired
private DataConnectionMapper dataConnectionMapper;
@Override
public List<DataConnection> getAll() {
return dataConnectionMapper.selectAll();
}
@Override
public List<DataConnection> getByOperator(String operator) {
return dataConnectionMapper.selectByOperator(operator);
}
@Override
public List<DataConnection> getByCondition(String operator, String date) {
return dataConnectionMapper.selectByCondition(operator, date);
}
@Override
public List<OperatorConnectionRateDTO> getOperatorConnectionRate(String startDate, String endDate) {
return dataConnectionMapper.selectOperatorConnectionRateByDateRange(startDate, endDate);
}
@Override
public List<OperatorConnectionRateDTO> getOperatorConnectionRate() {
return dataConnectionMapper.selectOperatorConnectionRate();
}
@Override
public List<DataConnection> getLatest10() {
return dataConnectionMapper.selectLatest10();
}
}

View File

@@ -0,0 +1,21 @@
package com.bigdata.service.impl;
import com.bigdata.dao.OrderMapper;
import com.bigdata.entity.Order;
import com.bigdata.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.List;
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private OrderMapper orderMapper;
@Override
public List<Order> getOrders() {
return orderMapper.getOrders();
}
}

View File

@@ -0,0 +1,46 @@
package com.bigdata.service.impl;
import com.bigdata.service.PhoenixQueryService;
import com.bigdata.util.PhoenixQueryUtil;
import org.springframework.stereotype.Service;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Phoenix 查询服务实现类
*/
@Service
public class PhoenixQueryServiceImpl implements PhoenixQueryService {
@Override
public List<PhoenixQueryUtil.OrderResult> queryOrders() {
return PhoenixQueryUtil.queryOrders();
}
@Override
public List<Map<String, Object>> executeCustomQuery(String sql) {
return PhoenixQueryUtil.executeQuery(sql, resultSet -> {
List<Map<String, Object>> results = new ArrayList<>();
ResultSetMetaData metaData = resultSet.getMetaData();
int columnCount = metaData.getColumnCount();
while (resultSet.next()) {
Map<String, Object> row = new HashMap<>();
for (int i = 1; i <= columnCount; i++) {
String columnName = metaData.getColumnName(i);
Object value = resultSet.getObject(i);
row.put(columnName, value);
}
results.add(row);
}
return results;
});
}
}

View File

@@ -0,0 +1,221 @@
package com.bigdata.util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
/**
* Phoenix 连接诊断工具
* 用于测试和排查 Phoenix 连接问题
*/
public class PhoenixConnectionDiagnostic {
/**
* 测试连接
* @param url Phoenix JDBC URL
* @return 连接测试结果
*/
public static ConnectionTestResult testConnection(String url) {
ConnectionTestResult result = new ConnectionTestResult();
result.setUrl(url);
result.setStartTime(System.currentTimeMillis());
Connection connection = null;
try {
// 标准的 JDBC 代码
// 1. 创建配置
// 没有需要添加的必要配置,因为 Phoenix 没有账号密码
Properties properties = new Properties();
// 2. 获取连接
// URL 格式jdbc:phoenix:host1,host2,host3:port/schema
// schema 指定要使用的数据库(库名),例如:/telecom
connection = DriverManager.getConnection(url, properties);
result.setSuccess(true);
result.setMessage("连接成功");
// 测试简单查询
try {
connection.createStatement().executeQuery("SELECT 1");
result.setQueryTestSuccess(true);
result.setQueryTestMessage("查询测试成功");
} catch (SQLException e) {
result.setQueryTestSuccess(false);
result.setQueryTestMessage("查询测试失败: " + e.getMessage());
}
} catch (SQLException e) {
result.setSuccess(false);
result.setMessage("连接失败: " + e.getMessage());
result.setException(e);
} finally {
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
// 忽略关闭异常
}
}
}
result.setEndTime(System.currentTimeMillis());
result.setDuration(result.getEndTime() - result.getStartTime());
return result;
}
/**
* 测试多个 URL
* @param urls URL 列表
* @return 测试结果列表
*/
public static List<ConnectionTestResult> testConnections(String... urls) {
List<ConnectionTestResult> results = new ArrayList<>();
for (String url : urls) {
results.add(testConnection(url));
}
return results;
}
/**
* 连接测试结果
*/
public static class ConnectionTestResult {
private String url;
private boolean success;
private String message;
private SQLException exception;
private boolean queryTestSuccess;
private String queryTestMessage;
private long startTime;
private long endTime;
private long duration;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public SQLException getException() {
return exception;
}
public void setException(SQLException exception) {
this.exception = exception;
}
public boolean isQueryTestSuccess() {
return queryTestSuccess;
}
public void setQueryTestSuccess(boolean queryTestSuccess) {
this.queryTestSuccess = queryTestSuccess;
}
public String getQueryTestMessage() {
return queryTestMessage;
}
public void setQueryTestMessage(String queryTestMessage) {
this.queryTestMessage = queryTestMessage;
}
public long getStartTime() {
return startTime;
}
public void setStartTime(long startTime) {
this.startTime = startTime;
}
public long getEndTime() {
return endTime;
}
public void setEndTime(long endTime) {
this.endTime = endTime;
}
public long getDuration() {
return duration;
}
public void setDuration(long duration) {
this.duration = duration;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("连接测试结果:\n");
sb.append(" URL: ").append(url).append("\n");
sb.append(" 状态: ").append(success ? "成功" : "失败").append("\n");
sb.append(" 消息: ").append(message).append("\n");
if (queryTestMessage != null) {
sb.append(" 查询测试: ").append(queryTestSuccess ? "成功" : "失败").append("\n");
sb.append(" 查询消息: ").append(queryTestMessage).append("\n");
}
sb.append(" 耗时: ").append(duration).append(" 毫秒\n");
if (exception != null) {
sb.append(" 异常: ").append(exception.getClass().getName()).append("\n");
sb.append(" 异常消息: ").append(exception.getMessage()).append("\n");
}
return sb.toString();
}
}
/**
* 主方法,用于测试连接
*/
public static void main(String[] args) {
System.out.println("=== Phoenix 连接诊断工具 ===\n");
// 测试多个 URL 格式格式jdbc:phoenix:host1,host2,host3:port/schema
String[] testUrls = {
// 使用主机名(正确格式,指定 telecom 库)
"jdbc:phoenix:hadoop102,hadoop103,hadoop104:2181/telecom",
// 使用 IP 地址(正确格式,指定 telecom 库)
"jdbc:phoenix:192.168.10.102,192.168.10.103,192.168.10.104:2181/telecom",
// 单个主机测试
"jdbc:phoenix:hadoop102:2181/telecom",
"jdbc:phoenix:192.168.10.102:2181/telecom"
};
List<ConnectionTestResult> results = testConnections(testUrls);
System.out.println("测试结果汇总:\n");
for (ConnectionTestResult result : results) {
System.out.println(result);
System.out.println("---");
}
// 找出成功的连接
System.out.println("\n可用的连接:");
for (ConnectionTestResult result : results) {
if (result.isSuccess()) {
System.out.println("" + result.getUrl());
}
}
}
}

View File

@@ -0,0 +1,229 @@
package com.bigdata.util;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
/**
* Phoenix JDBC 查询工具类
*/
public class PhoenixQueryUtil {
// Phoenix JDBC URL 格式jdbc:phoenix:host1,host2,host3:port/schema
// 注意:端口号在最后一个主机后面,表示所有主机共用同一个端口
// schema 指定要使用的数据库(库名),这里使用 telecom
// 如果使用主机名连接不上,可以尝试使用 IP 地址
private static final String PHOENIX_URL = "jdbc:phoenix:hadoop102,hadoop103,hadoop104:2181/telecom";
// 备用 URL使用 IP 地址)
private static final String PHOENIX_URL_IP = "jdbc:phoenix:192.168.10.102,192.168.10.103,192.168.10.104:2181/telecom";
/**
* 获取 Phoenix 连接
* @return Connection
* @throws SQLException
*/
public static Connection getConnection() throws SQLException {
return getConnection(PHOENIX_URL);
}
/**
* 获取 Phoenix 连接(使用自定义 URL
* @param url Phoenix JDBC URL
* @return Connection
* @throws SQLException
*/
public static Connection getConnection(String url) throws SQLException {
return getConnection(url, null);
}
/**
* 获取 Phoenix 连接(使用自定义 URL 和属性)
* @param url Phoenix JDBC URL格式jdbc:phoenix:host1,host2,host3:port/schema
* @param customProperties 自定义属性
* @return Connection
* @throws SQLException
*/
public static Connection getConnection(String url, Properties customProperties) throws SQLException {
// 1. 连接 URL格式jdbc:phoenix:host1,host2,host3:port/schema
// 2. 创建配置
// 没有需要添加的必要配置,因为 Phoenix 没有账号密码
Properties properties = new Properties();
if (customProperties != null) {
properties.putAll(customProperties);
}
// 可选配置
// properties.setProperty("phoenix.schema.isNamespaceMappingEnabled", "true");
// properties.setProperty("phoenix.schema.mapSystemTablesToNamespace", "true");
// 3. 获取连接
// Phoenix JDBC URL 格式jdbc:phoenix:host1,host2,host3:port/schema
// schema 指定要使用的数据库(库名),例如:/telecom
Connection connection = DriverManager.getConnection(url, properties);
return connection;
}
/**
* 尝试使用多个 URL 连接(如果主机名连接失败,尝试 IP 地址)
* @return Connection
* @throws SQLException
*/
public static Connection getConnectionWithFallback() throws SQLException {
// 先尝试使用主机名
try {
return getConnection(PHOENIX_URL);
} catch (SQLException e) {
System.err.println("使用主机名连接失败,尝试使用 IP 地址: " + e.getMessage());
// 如果主机名连接失败,尝试使用 IP 地址
return getConnection(PHOENIX_URL_IP);
}
}
/**
* 执行查询并返回结果集
* @param sql SQL 查询语句
* @return ResultSet
* @throws SQLException
*/
public static ResultSet executeQuery(String sql) throws SQLException {
Connection connection = getConnection();
Statement statement = connection.createStatement();
return statement.executeQuery(sql);
}
/**
* 查询订单列表
* @return List<Order> 订单列表
*/
public static List<OrderResult> queryOrders() {
List<OrderResult> orders = new ArrayList<>();
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
// 获取连接(如果主机名连接失败,会自动尝试 IP 地址)
connection = getConnectionWithFallback();
statement = connection.createStatement();
// 执行查询
String sql = "SELECT * FROM TB_ORDER";
resultSet = statement.executeQuery(sql);
// 处理结果集
while (resultSet.next()) {
OrderResult order = new OrderResult();
order.setId(resultSet.getLong("ID"));
order.setTotalAmount(resultSet.getLong("TOTAL_AMOUNT"));
order.setCreateTime(resultSet.getTimestamp("CREATE_TIME"));
orders.add(order);
}
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("查询订单失败: " + e.getMessage(), e);
} finally {
// 关闭资源
closeResources(resultSet, statement, connection);
}
return orders;
}
/**
* 执行自定义 SQL 查询
* @param sql SQL 语句
* @param handler ResultSet 处理器
* @param <T> 返回类型
* @return 查询结果
*/
public static <T> T executeQuery(String sql, ResultSetHandler<T> handler) {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
connection = getConnection();
statement = connection.createStatement();
resultSet = statement.executeQuery(sql);
return handler.handle(resultSet);
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("执行查询失败: " + e.getMessage(), e);
} finally {
closeResources(resultSet, statement, connection);
}
}
/**
* 关闭数据库资源
*/
private static void closeResources(ResultSet rs, Statement stmt, Connection conn) {
try {
if (rs != null) {
rs.close();
}
if (stmt != null) {
stmt.close();
}
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* ResultSet 处理器接口
*/
@FunctionalInterface
public interface ResultSetHandler<T> {
T handle(ResultSet rs) throws SQLException;
}
/**
* 订单查询结果类
*/
public static class OrderResult {
private Long id;
private Long totalAmount;
private Timestamp createTime;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getTotalAmount() {
return totalAmount;
}
public void setTotalAmount(Long totalAmount) {
this.totalAmount = totalAmount;
}
public Timestamp getCreateTime() {
return createTime;
}
public void setCreateTime(Timestamp createTime) {
this.createTime = createTime;
}
@Override
public String toString() {
return "OrderResult{" +
"id=" + id +
", totalAmount=" + totalAmount +
", createTime=" + createTime +
'}';
}
}
}

View File

@@ -0,0 +1,44 @@
server:
port: 8081
spring:
mvc:
view:
prefix: /WEB-INF/jsp/
suffix: .jsp
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: org.apache.phoenix.jdbc.PhoenixDriver
# Phoenix JDBC URL 格式jdbc:phoenix:host1,host2,host3:port/schema
# 注意:端口号在最后一个主机后面,表示所有主机共用同一个端口
# schema 指定要使用的数据库(库名)
url: jdbc:phoenix:192.168.10.102,192.168.10.103,192.168.10.104:2181/telecom
druid:
# 验证查询语句(用于测试连接是否有效)
validation-query: SELECT 1
# 验证查询超时时间(秒)
validation-query-timeout: 3
# 是否在空闲时验证连接
test-while-idle: true
# 是否在获取连接时验证连接
test-on-borrow: false
# 是否在归还连接时验证连接
test-on-return: false
# 连接池初始化大小
initial-size: 5
# 最小空闲连接数
min-idle: 5
# 最大活跃连接数
max-active: 20
# 获取连接等待超时时间(毫秒)
max-wait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
time-between-eviction-runs-millis: 60000
# 连接在池中最小生存时间,单位是毫秒
min-evictable-idle-time-millis: 300000
mybatis:
typeAliasesPackage: com.bigdata.entity
mapperLocations: classpath:mapper/*.xml
configuration:
mapUnderscoreToCamelCase: true

View File

@@ -0,0 +1,122 @@
<?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.bigdata.dao.DataConnectionMapper">
<!--
查询 Phoenix 表 DATACONNECTION
表名在 Phoenix 中是大写JDBC URL 中已指定 schema 为 telecom
-->
<!-- 查询所有数据 -->
<select id="selectAll" resultType="com.bigdata.entity.DataConnection">
SELECT
"ID" AS id,
"USER_LAT" AS userLat,
"USER_LON" AS userLon,
"NETWORK_NAME" AS networkId,
"NETWORK_TYPE" AS networkType,
"PING_VALUE" AS pingValue,
"MOBILE_NETWORK_TYPE" AS mobileNetworkType,
"TIME_INDEX_CLIENT" AS timeIndexClient
FROM "DATACONNECTION"
ORDER BY "TIME_INDEX_CLIENT" DESC
</select>
<!-- 按运营商查询数据 -->
<select id="selectByOperator" resultType="com.bigdata.entity.DataConnection">
SELECT
"ID" AS id,
"USER_LAT" AS userLat,
"USER_LON" AS userLon,
"NETWORK_NAME" AS networkId,
"NETWORK_TYPE" AS networkType,
"PING_VALUE" AS pingValue,
"MOBILE_NETWORK_TYPE" AS mobileNetworkType,
"TIME_INDEX_CLIENT" AS timeIndexClient
FROM "DATACONNECTION"
WHERE "NETWORK_NAME" = #{operator}
ORDER BY "TIME_INDEX_CLIENT" DESC
</select>
<!-- 按条件查询数据(支持运营商和日期) -->
<select id="selectByCondition" resultType="com.bigdata.entity.DataConnection">
SELECT
"ID" AS id,
"USER_LAT" AS userLat,
"USER_LON" AS userLon,
"NETWORK_NAME" AS networkId,
"NETWORK_TYPE" AS networkType,
"PING_VALUE" AS pingValue,
"MOBILE_NETWORK_TYPE" AS mobileNetworkType,
"TIME_INDEX_CLIENT" AS timeIndexClient
FROM "DATACONNECTION"
<where>
<if test="operator != null and operator != ''">
AND "NETWORK_NAME" = #{operator}
</if>
<if test="date != null and date != ''">
AND "TIME_INDEX_CLIENT" &gt;= TO_TIMESTAMP(CONCAT(#{date}, ' 00:00:00'), 'yyyy-MM-dd HH:mm:ss')
AND "TIME_INDEX_CLIENT" &lt; TO_TIMESTAMP(CONCAT(#{date}, ' 23:59:59'), 'yyyy-MM-dd HH:mm:ss')
</if>
</where>
ORDER BY "TIME_INDEX_CLIENT" DESC
</select>
<!-- 统计各运营商的连接率(支持时间范围) -->
<select id="selectOperatorConnectionRateByDateRange" resultType="com.bigdata.dto.OperatorConnectionRateDTO">
SELECT
"NETWORK_NAME" AS operator,
CAST(COUNT(*) AS BIGINT) AS totalCount,
CAST(SUM(CASE WHEN "PING_VALUE" IS NOT NULL AND "PING_VALUE" != '' THEN 1 ELSE 0 END) AS BIGINT) AS successCount,
CAST(ROUND(
SUM(CASE WHEN "PING_VALUE" IS NOT NULL AND "PING_VALUE" != '' THEN 1 ELSE 0 END) * 100.0 / COUNT(*),
2
) AS DOUBLE) AS connectionRate
FROM "DATACONNECTION"
<where>
"NETWORK_NAME" IN ('CMCC', 'CUCC', 'CTCC')
<if test="startDate != null and startDate != ''">
AND "TIME_INDEX_CLIENT" &gt;= TO_TIMESTAMP(CONCAT(#{startDate}, ' 00:00:00'), 'yyyy-MM-dd HH:mm:ss')
</if>
<if test="endDate != null and endDate != ''">
AND "TIME_INDEX_CLIENT" &lt;= TO_TIMESTAMP(CONCAT(#{endDate}, ' 23:59:59'), 'yyyy-MM-dd HH:mm:ss')
</if>
</where>
GROUP BY "NETWORK_NAME"
ORDER BY "NETWORK_NAME"
</select>
<!-- 统计各运营商的连接率(无时间范围,保留原方法) -->
<select id="selectOperatorConnectionRate" resultType="com.bigdata.dto.OperatorConnectionRateDTO">
SELECT
"NETWORK_NAME" AS operator,
CAST(COUNT(*) AS BIGINT) AS totalCount,
CAST(SUM(CASE WHEN "PING_VALUE" IS NOT NULL AND "PING_VALUE" != '' THEN 1 ELSE 0 END) AS BIGINT) AS successCount,
CAST(ROUND(
SUM(CASE WHEN "PING_VALUE" IS NOT NULL AND "PING_VALUE" != '' THEN 1 ELSE 0 END) * 100.0 / COUNT(*),
2
) AS DOUBLE) AS connectionRate
FROM "DATACONNECTION"
WHERE "NETWORK_NAME" IN ('CMCC', 'CUCC', 'CTCC')
GROUP BY "NETWORK_NAME"
ORDER BY "NETWORK_NAME"
</select>
<!-- 查询最新的 10 条数据(保留原方法) -->
<select id="selectLatest10" resultType="com.bigdata.entity.DataConnection">
SELECT
"ID" AS id,
"USER_LAT" AS userLat,
"USER_LON" AS userLon,
"NETWORK_NAME" AS networkId,
"NETWORK_TYPE" AS networkType,
"PING_VALUE" AS pingValue,
"MOBILE_NETWORK_TYPE" AS mobileNetworkType,
"TIME_INDEX_CLIENT" AS timeIndexClient
FROM "DATACONNECTION"
ORDER BY "TIME_INDEX_CLIENT" DESC
LIMIT 10
</select>
</mapper>

View File

@@ -0,0 +1,88 @@
<?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.bigdata.dao.NWQualityMapper">
<!--
查询 Phoenix 表 NWQUALITY
表名在 Phoenix 中是大写JDBC URL 中已指定 schema
-->
<!-- 按条件查询网络质量数据 -->
<select id="selectByCondition" resultType="com.bigdata.entity.NWQuality">
SELECT
"ID" AS id,
"GPSLAT" AS gpsLat,
"GPSLON" AS gpsLon,
"NWOPERATOR" AS nwOperator,
"ULSPEED" AS ulSpeed,
"DLSPEED" AS dlSpeed,
"LATENCY" AS latency,
"PROVINCE" AS province,
"DAYTIME" AS daytime,
"NWTYPE" AS nwType,
"LANDMARK" AS landmark,
"COMPANYMODEL" AS companyModel
FROM "NWQUALITY"
<where>
<if test="operator != null and operator != ''">
AND "PROVINCE" LIKE CONCAT('%', #{operator})
</if>
<if test="startDate != null and startDate != ''">
AND "DAYTIME" &gt;= TO_TIMESTAMP(CONCAT(#{startDate}, ' 00:00:00'), 'yyyy-MM-dd HH:mm:ss')
</if>
<if test="endDate != null and endDate != ''">
AND "DAYTIME" &lt;= TO_TIMESTAMP(CONCAT(#{endDate}, ' 23:59:59'), 'yyyy-MM-dd HH:mm:ss')
</if>
</where>
ORDER BY "DAYTIME" DESC
</select>
<!-- 统计各地区数量 -->
<select id="selectRegionStatistics" resultType="com.bigdata.dto.RegionStatisticsDTO">
SELECT
CASE
WHEN "PROVINCE" LIKE '%电信%' THEN REPLACE("PROVINCE", '电信', '')
WHEN "PROVINCE" LIKE '%移动%' THEN REPLACE("PROVINCE", '移动', '')
WHEN "PROVINCE" LIKE '%联通%' THEN REPLACE("PROVINCE", '联通', '')
WHEN "PROVINCE" LIKE '%铁通%' THEN REPLACE("PROVINCE", '铁通', '')
ELSE "PROVINCE"
END AS region,
CASE
WHEN "PROVINCE" LIKE '%电信%' THEN '电信'
WHEN "PROVINCE" LIKE '%移动%' THEN '移动'
WHEN "PROVINCE" LIKE '%联通%' THEN '联通'
WHEN "PROVINCE" LIKE '%铁通%' THEN '铁通'
ELSE '未知'
END AS operator,
CAST(COUNT(*) AS BIGINT) AS count
FROM "NWQUALITY"
<where>
<if test="operator != null and operator != ''">
AND "PROVINCE" LIKE CONCAT('%', #{operator})
</if>
<if test="startDate != null and startDate != ''">
AND "DAYTIME" &gt;= TO_TIMESTAMP(CONCAT(#{startDate}, ' 00:00:00'), 'yyyy-MM-dd HH:mm:ss')
</if>
<if test="endDate != null and endDate != ''">
AND "DAYTIME" &lt;= TO_TIMESTAMP(CONCAT(#{endDate}, ' 23:59:59'), 'yyyy-MM-dd HH:mm:ss')
</if>
</where>
GROUP BY
CASE
WHEN "PROVINCE" LIKE '%电信%' THEN REPLACE("PROVINCE", '电信', '')
WHEN "PROVINCE" LIKE '%移动%' THEN REPLACE("PROVINCE", '移动', '')
WHEN "PROVINCE" LIKE '%联通%' THEN REPLACE("PROVINCE", '联通', '')
WHEN "PROVINCE" LIKE '%铁通%' THEN REPLACE("PROVINCE", '铁通', '')
ELSE "PROVINCE"
END,
CASE
WHEN "PROVINCE" LIKE '%电信%' THEN '电信'
WHEN "PROVINCE" LIKE '%移动%' THEN '移动'
WHEN "PROVINCE" LIKE '%联通%' THEN '联通'
WHEN "PROVINCE" LIKE '%铁通%' THEN '铁通'
ELSE '未知'
END
ORDER BY count DESC, region
</select>
</mapper>

View File

@@ -0,0 +1,9 @@
<?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.bigdata.dao.OrderMapper">
<select id="getOrders" resultType="Order">
select * from tb_order
</select>
</mapper>