前言
在大数据爆发的今天,实时数据分析已成为企业决策的核心支撑 —— 电商需要实时监控爆款库存,运维需要秒级定位系统异常,营销需要实时调整投放策略。而作为传统关系型数据库的代表,MySQL 在中小规模数据存储和简单查询场景中表现稳定,但面对千万级以上数据量的复杂聚合分析(如多维度统计、漏斗转化计算)时,往往陷入查询超时、性能暴跌的困境,难以满足实时性需求。
此时,Apache Doris 这款高性能 MPP 分析型数据库应运而生,它专为实时数据分析场景设计,完美弥补了 MySQL 的短板。
本文将带大家实战 Spring Boot 与 Apache Doris 的集成方案,看看如何用它替代 MySQL,轻松搞定高并发、大数据量的实时分析需求!
救星登场:Apache Doris 闪亮来袭
什么是 Apache Doris?
Apache Doris 是一款基于 MPP(Massively Parallel Processing,大规模并行处理)架构的开源分析型数据库,起源于百度,2018 年开源并捐赠给 Apache 基金会。
它专为 OLAP(在线分析处理)场景设计,核心定位是 “实时、高效、易用”,支持 PB 级数据的低延迟查询,无需复杂的分库分表或数据预处理,就能直接应对多维度、高并发的分析需求。

核心特性,碾压 MySQL 的关键
1、极致查询性能: MPP 架构让数据在多个节点并行计算,单查询响应时间可低至毫秒级,比 MySQL 在大数据量下的查询速度快 10-100 倍;
2、实时数据接入: 支持从 Kafka、Flink 等流处理框架实时导入数据,也可同步 MySQL、Hive 等数据源,数据延迟低至秒级;
3、兼容 MySQL 协议: 无需修改业务代码中的 SQL 语法,支持 JDBC/ODBC 连接,集成成本极低;
4、高并发支持: 可轻松支撑每秒数千次的查询请求,适合面向用户的分析型应用(如数据看板、自助分析平台);
5、极简运维: 支持单节点部署,也可横向扩展至数百节点,自动分片、负载均衡,无需复杂的集群管理。
Doris vs MySQL:适用场景对比

一句话总结:MySQL 适合 “写多查少” 的业务交易场景(如订单创建、用户注册),Apache Doris 适合 “读多写少” 的实时分析场景(如数据统计、报表生成)。
Spring Boot 集成 Apache Doris 实战
前期准备
- 环境要求:
JDK 1.8+、Spring Boot 2.3+、Maven 3.6+;
- Apache Doris 部署: 推荐使用 Docker 快速部署(适合测试),或参考官方文档部署集群;
- 核心依赖: Doris JDBC 驱动(兼容 MySQL 协议,可直接使用 MySQL JDBC 驱动)。
第一步:创建 Spring Boot 项目
1.访问 Spring Initializr,选择:
- Spring Boot 版本: 2.7.x(稳定版);
- 依赖: Spring Web(提供接口)、Spring Data JPA(简化数据操作)、MySQL Driver(兼容 Doris);
2.下载项目后,解压并导入 IDEA,项目基本结构如下:
src/
├── main/
│ ├── java/com/example/dorisdemo/
│ │ ├── controller/ // 接口层
│ │ ├── entity/ // 实体类
│ │ ├── repository/ // 数据访问层
│ │ ├── service/ // 业务层
│ │ └── DorisDemoApplication.java // 启动类
│ └── resources/
│ └── application.yml // 配置文件
└── pom.xml // 依赖配置
第二步:核心配置(关键步骤)
1、 配置 pom.xml 依赖
无需额外引入 Doris 专属依赖,直接使用 MySQL JDBC 驱动即可(Doris 兼容 MySQL 协议),在 pom.xml 中添加:
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-jpaartifactId>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<scope>runtimescope>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<optional>trueoptional>
dependency>
2、 配置 application.yml
在
resources 目录下创建 application.yml,配置 Doris 连接信息(重点注意 url 格式):
spring:
# 数据库配置(Doris兼容MySQL协议)
datasource:
url:jdbc:mysql://127.0.0.1:9030/demo_db?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
username:root# Doris默认用户名
password:123456# 部署时设置的密码
driver-class-name:com.mysql.cj.jdbc.Driver
# JPA配置(简化CRUD操作)
jpa:
hibernate:
ddl-auto:none# 关闭自动建表(Doris表手动创建)
properties:
hibernate:
dialect:org.hibernate.dialect.MySQL8Dialect
format_sql:true# 格式化SQL日志
show-sql:true# 打印SQL语句
# 日志配置(可选)
logging:
level:
org.springframework.data.jpa:debug
com.example.dorisdemo:info
说明:Doris 的 JDBC 连接端口默认是 9030(FE 查询端口),demo_db是提前在 Doris 中创建的数据库。
第三步:创建 Doris 数据表
在 Doris 中手动创建测试表(以电商用户行为表为例),执行 SQL:
-- 创建数据库
CREATE
DATABASEIFNOTEXISTS demo_db;
USE demo_db;
-- 创建用户行为表(分区表,按日期分区)
CREATETABLEIFNOTEXISTS user_behavior (
user_id BIGINTCOMMENT'用户ID',
product_id BIGINTCOMMENT'商品ID',
category_id INTCOMMENT'商品分类ID',
behavior_type VARCHAR(20) COMMENT'行为类型(click/purchase/collect)',
create_time DATETIME COMMENT'行为时间'
) ENGINE=OLAP
DUPLICATEKEY(user_id, product_id)
PARTITIONBYRANGE(create_time) (
PARTITION p202401 VALUESLESSTHAN ('2024-02-01'),
PARTITION p202402 VALUESLESSTHAN ('2024-03-01')
)
DISTRIBUTEDBYHASH(user_id) BUCKETS 10
PROPERTIES (
"storage_medium" = "HDD",
"storage_ttl" = "30 DAY"
);
说明:Doris 支持分区表、分桶表,通过PARTITION BY和DISTRIBUTED BY优化查询性能,适合大数据量存储。
第四步:编写代码实现业务逻辑
1、 实体类(Entity)
映射 Doris 的user_behavior表:
package com.example.dorisdemo.entity;
import lombok.Data;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import javax.persistence.*;
import java.time.LocalDateTime;
@Data
@Entity
@Table(name = "user_behavior") // 对应Doris表名
@DynamicInsert// 动态插入(只插入非空字段)
@DynamicUpdate// 动态更新(只更新修改字段)
publicclass UserBehavior {
@Id// 主键(Doris无自增主键,需手动指定)
@Column(name = "user_id")
private Long userId;
@Column(name = "product_id")
private Long productId;
@Column(name = "category_id")
private Integer categoryId;
@Column(name = "behavior_type")
private String behaviorType; // click/purchase/collect
@Column(name = "create_time")
private LocalDateTime createTime;
}
2、 数据访问层(Repository)
继承 JpaRepository,简化 CRUD 操作:
package com.example.dorisdemo.repository;
import com.example.dorisdemo.entity.UserBehavior;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.time.LocalDateTime;
import java.util.List;
@Repository
publicinterface UserBehaviorRepository extends JpaRepository<UserBehavior, Long> {
// 自定义查询:查询指定日期范围内的用户行为
List findByCreateTimeBetween(LocalDateTime start, LocalDateTime end);
// 复杂查询:统计指定分类的商品点击量(Doris优化的聚合查询)
@Query(value = "SELECT COUNT(*) FROM user_behavior WHERE category_id = :categoryId AND behavior_type = 'click' AND create_time BETWEEN :start AND :end", nativeQuery = true)
Long countClickByCategoryId(@Param("categoryId") Integer categoryId,
@Param("start") LocalDateTime start,
@Param("end") LocalDateTime end);
}
3、 业务层(Service)
实现核心业务逻辑:
package com.example.dorisdemo.service;
import com.example.dorisdemo.entity.UserBehavior;
import com.example.dorisdemo.repository.UserBehaviorRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.List;
@Service
@RequiredArgsConstructor// 构造器注入依赖
publicclass UserBehaviorService {
privatefinal UserBehaviorRepository behaviorRepository;
// 保存用户行为数据
public UserBehavior save
(UserBehavior behavior) {
return behaviorRepository.save(behavior);
}
// 批量保存(适合批量导入数据)
public List batchSave(List behaviors) {
return behaviorRepository.saveAll(behaviors);
}
// 查询指定日期范围的行为数据
public List getBehaviorByDateRange(LocalDateTime start, LocalDateTime end) {
return behaviorRepository.findByCreateTimeBetween(start, end);
}
// 统计分类商品点击量(实时分析核心接口)
public Long getCategoryClickCount(Integer categoryId, LocalDateTime start, LocalDateTime end) {
return behaviorRepository.countClickByCategoryId(categoryId, start, end);
}
}
4、接口层(Controller)
提供 HTTP 接口供前端调用:
package com.example.dorisdemo.controller;
import com.example.dorisdemo.entity.UserBehavior;
import com.example.dorisdemo.service.UserBehaviorService;
import lombok.RequiredArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.List;
@RestController
@RequestMapping("/user-behavior")
@RequiredArgsConstructor
publicclass UserBehaviorController {
privatefinal UserBehaviorService behaviorService;
// 保存单个行为数据
@PostMapping
public UserBehavior save(@RequestBody UserBehavior behavior) {
return behaviorService.save(behavior);
}
// 批量保存行为数据
@PostMapping("/batch")
public List batchSave(@RequestBody List behaviors) {
return behaviorService.batchSave(behaviors);
}
// 按日期范围查询
@GetMapping("/range")
public List getByRange(
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime start,
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime end) {
return behaviorService.getBehaviorByDateRange(start, end);
}
// 统计分类点击量(实时分析接口)
@GetMapping("/click-count")
public Long getClickCount(
@RequestParam Integer categoryId,
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime start,
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime end) {
return behaviorService.getCategoryClickCount(categoryId, start, end);
}
}
第五步:测试与验证
1、 启动项目
运行DorisDemoApplication.java,确保项目启动成功,无报错。
2、 接口测试(用 Postman 或 curl)
批量插入测试数据:
POST /user-behavior/batch
Content-Type: application/json
[
{"userId":1001,"productId":2001,"categoryId":301,"behaviorType":"click","createTime":"2024-01-15 10:30:00"},
{"userId":1002,"productId":2002,"categoryId":301,"behaviorType":"click",
"createTime":"2024-01-15 11:20:00"},
{"userId":1003,"productId":2003,"categoryId":302,"behaviorType":"purchase","createTime":"2024-01-15 14:10:00"}
]
统计 301 分类的点击量:
GET /user-behavior/click-count?categoryId=301&start=2024-01-01 00:00:00&end=2024-01-31 23:59:59
3、性能对比测试
用 100 万条用户行为数据进行测试,对比 MySQL 和 Doris 的查询性能:

可以看到,Doris 在分析场景下的性能远超 MySQL,且数据量越大,优势越明显。
小结
Spring Boot 与 Apache Doris 的集成极其简单(兼容 MySQL 协议和 JDBC 驱动),但带来的性能提升却是革命性的 —— 它让开发者无需关注复杂的分布式架构,就能快速实现 PB 级数据的实时分析能力,完美替代 MySQL 在 OLAP 场景中的不足。
未来,随着实时数据需求的进一步增长,Apache Doris 这类专注于分析场景的数据库将成为技术栈的标配。无论是电商、金融、物流还是政务领域,只要涉及大数据量的实时统计、报表生成、多维度分析,“Spring Boot + Apache Doris” 都是值得优先选择的方案。
如果你还在为 MySQL 的分析性能瓶颈烦恼,不妨试试这个组合,相信会给你带来惊喜!欢迎在评论区分享你的使用体验或疑问~