commit e3f3cdd3361034babe70260ff9ac299cabf11c81
Author: wangran <3189505710@qq.com>
Date: Fri Jan 9 11:32:52 2026 +0800
初始化项目
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5ff6309
--- /dev/null
+++ b/.gitignore
@@ -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
\ No newline at end of file
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..35410ca
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# 默认忽略的文件
+/shelf/
+/workspace.xml
+# 基于编辑器的 HTTP 客户端请求
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..aa00ffa
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..132404b
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..255ac54
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,74 @@
+
+ 4.0.0
+ com.bigdata
+ SpringPhoenix
+ war
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.7.0
+
+
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+ 2.2.2
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+
+ javax.servlet
+ jstl
+
+
+
+
+ org.apache.tomcat.embed
+ tomcat-embed-jasper
+ provided
+
+
+
+
+ org.apache.phoenix
+ phoenix-client-hbase-2.4
+ 5.1.2
+
+
+
+ org.apache.hadoop
+ hadoop-common
+ 2.8.4
+
+
+
+ com.alibaba
+ druid
+ 1.2.3
+
+
+
+ org.projectlombok
+ lombok
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/com/bigdata/SpringbootPhoenixApplication.java b/src/main/java/com/bigdata/SpringbootPhoenixApplication.java
new file mode 100644
index 0000000..74f27b7
--- /dev/null
+++ b/src/main/java/com/bigdata/SpringbootPhoenixApplication.java
@@ -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);
+ }
+}
diff --git a/src/main/java/com/bigdata/config/CorsConfig.java b/src/main/java/com/bigdata/config/CorsConfig.java
new file mode 100644
index 0000000..dd3c0c9
--- /dev/null
+++ b/src/main/java/com/bigdata/config/CorsConfig.java
@@ -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);
+ }
+}
diff --git a/src/main/java/com/bigdata/config/DataSourceConfig.java b/src/main/java/com/bigdata/config/DataSourceConfig.java
new file mode 100644
index 0000000..d006316
--- /dev/null
+++ b/src/main/java/com/bigdata/config/DataSourceConfig.java
@@ -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;
+ }
+}
diff --git a/src/main/java/com/bigdata/config/PhoenixConfig.java b/src/main/java/com/bigdata/config/PhoenixConfig.java
new file mode 100644
index 0000000..1db7500
--- /dev/null
+++ b/src/main/java/com/bigdata/config/PhoenixConfig.java
@@ -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;
+ }
+}
diff --git a/src/main/java/com/bigdata/controller/DataConnectionController.java b/src/main/java/com/bigdata/controller/DataConnectionController.java
new file mode 100644
index 0000000..c38a7ac
--- /dev/null
+++ b/src/main/java/com/bigdata/controller/DataConnectionController.java
@@ -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 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 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 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 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;
+ }
+}
+
diff --git a/src/main/java/com/bigdata/controller/OrderController.java b/src/main/java/com/bigdata/controller/OrderController.java
new file mode 100644
index 0000000..746a4b4
--- /dev/null
+++ b/src/main/java/com/bigdata/controller/OrderController.java
@@ -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 list = this.orderService.getOrders();
+
+ List ids=new ArrayList<>();
+ List 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";
+ }
+
+}
diff --git a/src/main/java/com/bigdata/controller/PhoenixDiagnosticController.java b/src/main/java/com/bigdata/controller/PhoenixDiagnosticController.java
new file mode 100644
index 0000000..4369f21
--- /dev/null
+++ b/src/main/java/com/bigdata/controller/PhoenixDiagnosticController.java
@@ -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 testConnections(
+ @RequestParam String urls) {
+ String[] urlArray = urls.split(",");
+ return PhoenixConnectionDiagnostic.testConnections(urlArray);
+ }
+}
diff --git a/src/main/java/com/bigdata/controller/PhoenixQueryController.java b/src/main/java/com/bigdata/controller/PhoenixQueryController.java
new file mode 100644
index 0000000..071f934
--- /dev/null
+++ b/src/main/java/com/bigdata/controller/PhoenixQueryController.java
@@ -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 getOrders() {
+ return phoenixQueryService.queryOrders();
+ }
+
+ /**
+ * 执行自定义 SQL 查询
+ * @param sql SQL 查询语句
+ * @return 查询结果
+ */
+ @PostMapping("/query")
+ public List