在大数据爆发的今天,实时数据分析已成为企业决策的核心支撑。电商需要实时监控爆款库存,运维需要秒级定位系统异常,营销需要实时调整投放策略。而作为传统关系型数据库的代表,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 项目
- 访问Spring Initializr,选择:
- Spring Boot 版本: 2.7.x(稳定版);
- 依赖: Spring Web(提供接口)、Spring Data JPA(简化数据操作)、MySQL Driver(兼容Doris);
- 下载项目后,解压并导入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中添加:
<!-- Spring Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Data JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- MySQL JDBC驱动(兼容Doris) -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- lombok(简化实体类) -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</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 DATABASE IF NOT EXISTS demo_db;
USE demo_db;
-- 创建用户行为表(分区表,按日期分区)
CREATE TABLE IF NOT EXISTS user_behavior (
user_id BIGINT COMMENT '用户ID',
product_id BIGINT COMMENT '商品ID',
category_id INT COMMENT '商品分类ID',
behavior_type VARCHAR(20) COMMENT '行为类型(click/purchase/collect)',
create_time DATETIME COMMENT '行为时间'
)
ENGINE=OLAP
DUPLICATE KEY(user_id, product_id)
PARTITION BY RANGE(create_time) (
PARTITION p202401 VALUES LESS THAN ('2024-02-01'),
PARTITION p202402 VALUES LESS THAN ('2024-03-01')
)
DISTRIBUTED BY HASH(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 // 动态更新(只更新修改字段)
public class 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
public interface UserBehaviorRepository extends JpaRepository<UserBehavior, Long> {
// 自定义查询:查询指定日期范围内的用户行为
List<UserBehavior> 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 // 构造器注入依赖
public class UserBehaviorService {
private final UserBehaviorRepository behaviorRepository;
// 保存用户行为数据
public UserBehavior save(UserBehavior behavior) {
return behaviorRepository.save(behavior);
}
// 批量保存(适合批量导入数据)
public List<UserBehavior> batchSave(List<UserBehavior> behaviors) {
return behaviorRepository.saveAll(behaviors);
}
// 查询指定日期范围的行为数据
public List<UserBehavior> 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
public class UserBehaviorController {
private final UserBehaviorService behaviorService;
// 保存单个行为数据
@PostMapping
public UserBehavior save(@RequestBody UserBehavior behavior) {
return behaviorService.save(behavior);
}
// 批量保存行为数据
@PostMapping("/batch")
public List<UserBehavior> batchSave(@RequestBody List<UserBehavior> behaviors) {
return behaviorService.batchSave(behaviors);
}
// 按日期范围查询
@GetMapping("/range")
public List<UserBehavior> 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的集成极其简单,但带来的性能提升却是革命性的。它让开发者无需关注复杂的分布式架构,就能快速实现PB级数据的实时分析能力,完美解决MySQL在OLAP场景中的性能瓶颈。未来,随着大数据实时分析需求的增长,Apache Doris这类专注于分析场景的数据库将成为技术栈的重要组成。无论是电商、金融还是物流领域,只要涉及大数据量的实时统计与多维度分析,“Spring Boot + Apache Doris”都是一个高效且值得考虑的方案。