Spring Boot数据访问(JDBC)全解析:从基础配置到高级调优
文章目录
- 引言
- 一、Spring Boot JDBC核心架构
- 1.1 核心组件关系图
- 1.2 自动配置逻辑
- 二、基础配置实践
- 2.1 数据源配置
- 2.2 多数据源配置
- 三、JdbcTemplate深度使用
- 3.1 基础CRUD操作
- 3.2 批处理优化
- 四、事务管理
- 4.1 声明式事务
- 4.2 事务传播机制
- 五、异常处理
- 5.1 Spring异常体系
- 5.2 自定义异常处理
- 六、性能优化策略
- 6.1 SQL监控配置
- 6.2 连接池调优参数
- 七、生产环境最佳实践
- 总结
引言
在Spring Boot应用中,JDBC仍然是关系型数据库访问的基石。尽管JPA等ORM框架日益流行,但在需要精细控制SQL、处理复杂查询或追求极致性能的场景下,原生JDBC仍具有不可替代的优势。本文将深入探讨Spring Boot中JDBC数据访问的全流程实现,涵盖从基础配置到生产级优化的关键技术要点。
一、Spring Boot JDBC核心架构
1.1 核心组件关系图
graph TDA[DataSource] --> B[JdbcTemplate]B --> C[NamedParameterJdbcTemplate]A --> D[TransactionManager]D --> E[@Transactional]
1.2 自动配置逻辑
- 条件触发:检测到
spring-jdbc存在时自动配置 - 默认行为:
- 自动配置HikariCP连接池
- 创建JdbcTemplate/NamedParameterJdbcTemplate
- 注册PlatformTransactionManager
二、基础配置实践
2.1 数据源配置
# application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/mydb?useSSL=false
spring.datasource.username=root
spring.datasource.password=secret
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver# HikariCP优化配置
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.maximum-pool-size=20
spring.datasource.hikari.idle-timeout=600000
2.2 多数据源配置
@Configuration
public class MultiDataSourceConfig {@Bean@Primary@ConfigurationProperties("app.datasource.primary")public DataSource primaryDataSource() {return DataSourceBuilder.create().build();}@Bean@ConfigurationProperties("app.datasource.secondary")public DataSource secondaryDataSource() {return DataSourceBuilder.create().build();}@Beanpublic JdbcTemplate primaryJdbcTemplate(@Qualifier("primaryDataSource") DataSource dataSource) {return new JdbcTemplate(dataSource);}
}
三、JdbcTemplate深度使用
3.1 基础CRUD操作
@Repository
public class UserRepository {private final JdbcTemplate jdbcTemplate;public UserRepository(JdbcTemplate jdbcTemplate) {this.jdbcTemplate = jdbcTemplate;}// 插入操作public Long createUser(User user) {String sql = "INSERT INTO users (name, email) VALUES (?, ?)";KeyHolder keyHolder = new GeneratedKeyHolder();jdbcTemplate.update(connection -> {PreparedStatement ps = connection.prepareStatement(sql, new String[]{"id"});ps.setString(1, user.getName());ps.setString(2, user.getEmail());return ps;}, keyHolder);return keyHolder.getKey().longValue();}// 查询操作public User findById(Long id) {String sql = "SELECT * FROM users WHERE id = ?";return jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(User.class), id);}
}
3.2 批处理优化
public void batchInsert(List<User> users) {jdbcTemplate.batchUpdate("INSERT INTO users (name, email) VALUES (?, ?)",new BatchPreparedStatementSetter() {@Overridepublic void setValues(PreparedStatement ps, int i) throws SQLException {User user = users.get(i);ps.setString(1, user.getName());ps.setString(2, user.getEmail());}@Overridepublic int getBatchSize() {return users.size();}});
}
四、事务管理
4.1 声明式事务
@Service
public class OrderService {private final JdbcTemplate jdbcTemplate;public OrderService(JdbcTemplate jdbcTemplate) {this.jdbcTemplate = jdbcTemplate;}@Transactionalpublic void placeOrder(Order order) {// 扣减库存jdbcTemplate.update("UPDATE products SET stock = stock - ? WHERE id = ?", order.getQuantity(), order.getProductId());// 创建订单jdbcTemplate.update("INSERT INTO orders (user_id, product_id, quantity) VALUES (?, ?, ?)",order.getUserId(), order.getProductId(), order.getQuantity());}
}
4.2 事务传播机制
| 传播行为 | 说明 |
|---|---|
| REQUIRED(默认) | 支持当前事务,不存在则新建 |
| REQUIRES_NEW | 新建独立事务,挂起当前事务 |
| NESTED | 嵌套事务(需要数据库支持) |
| NOT_SUPPORTED | 非事务方式运行,挂起当前事务 |
五、异常处理
5.1 Spring异常体系
5.2 自定义异常处理
@ControllerAdvice
public class JdbcExceptionHandler {@ExceptionHandler(DataIntegrityViolationException.class)public ResponseEntity<String> handleConstraintViolation(DataIntegrityViolationException ex) {return ResponseEntity.badRequest().body("数据完整性校验失败:" + ex.getRootCause().getMessage());}@ExceptionHandler(DataAccessException.class)public ResponseEntity<String> handleDataAccessException(DataAccessException ex) {return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("数据库访问异常:" + ex.getMessage());}
}
六、性能优化策略
6.1 SQL监控配置
# 启用JDBC日志
logging.level.org.springframework.jdbc=DEBUG
logging.level.org.springframework.transaction=TRACE# 使用P6Spy进行SQL分析
spring.datasource.driver-class-name=com.p6spy.engine.spy.P6SpyDriver
spring.datasource.url=jdbc:p6spy:mysql://localhost:3306/mydb
6.2 连接池调优参数
| 参数 | 推荐值 | 说明 |
|---|---|---|
| maximumPoolSize | CPU核心数*2 | 最大连接数 |
| minimumIdle | 10 | 最小空闲连接 |
| connectionTimeout | 30000ms | 连接获取超时时间 |
| idleTimeout | 600000ms | 空闲连接回收时间 |
| maxLifetime | 1800000ms | 连接最大存活时间 |
七、生产环境最佳实践
-
SQL管理规范
- 使用SQL文件集中管理
- 采用Flyway/Liquibase进行版本控制
-- V1__create_users_table.sql CREATE TABLE users (id BIGINT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(50) NOT NULL,email VARCHAR(100) UNIQUE ); -
防御式编程
public Optional<User> safeFindUser(Long id) {try {return Optional.ofNullable(jdbcTemplate.queryForObject("SELECT * FROM users WHERE id = ?", new BeanPropertyRowMapper<>(User.class), id));} catch (EmptyResultDataAccessException ex) {return Optional.empty();} } -
对象映射优化
public class CustomRowMapper implements RowMapper<User> {@Overridepublic User mapRow(ResultSet rs, int rowNum) throws SQLException {return User.builder().id(rs.getLong("id")).name(rs.getString("name")).email(rs.getString("email")).build();} }
总结
Spring Boot JDBC的核心优势:
- 轻量高效:直接操作SQL,避免ORM框架开销
- 灵活可控:完全掌控SQL执行细节
- 生态完善:与Spring事务体系无缝集成
- 性能卓越:配合连接池可达万级TPS
建议在以下场景优先选择JDBC方案:
- 需要执行复杂SQL查询
- 处理大批量数据操作
- 对性能要求极高的核心业务
- 已有成熟SQL需要复用
通过合理运用JdbcTemplate+事务管理+连接池调优的组合策略,可以构建出既保持灵活性又具备高性能的数据访问层。对于新项目,建议结合Spring Data JDBC以获得更好的领域模型支持。
相关文章:
Spring Boot数据访问(JDBC)全解析:从基础配置到高级调优
文章目录 引言一、Spring Boot JDBC核心架构1.1 核心组件关系图1.2 自动配置逻辑 二、基础配置实践2.1 数据源配置2.2 多数据源配置 三、JdbcTemplate深度使用3.1 基础CRUD操作3.2 批处理优化 四、事务管理4.1 声明式事务4.2 事务传播机制 五、异常处理5.1 Spring异常体系5.2 自…...
三数之和:经典问题的多种优化策略
三数之和:经典问题的多种优化策略 大家好,我是Echo_Wish。今天我们来聊一个经典的算法问题——三数之和(3Sum)。它是许多面试和算法竞赛中常见的问题之一,也常常考察我们对算法优化的理解和技巧。我们不仅要解决问题&…...
信息学奥赛一本通 1520:【 例 1】分离的路径 | 洛谷 P2860 [USACO06JAN]Redundant Paths G
【题目链接】 ybt 1520:【 例 1】分离的路径 洛谷 P2860 [USACO06JAN]Redundant Paths G 【题目考点】 1. 图论:割边(桥) 边双连通分量 【解题思路】 每个草场是一个顶点,草场之间的双向路是无向边,该…...
架构师面试(六):熔断和降级
问题 在千万日活的电商系统中,商品列表页服务通过 RPC 调用广告服务;经过统计发现,在最近10秒的时间里,商品列表页服务在对广告服务的调用中有 98% 的调用是超时的; 针对这个场景,下面哪几项的说法是正确的…...
使用 DeepSeek 生成流程图、甘特图与思维导图:结合 Typora 和 XMind 的高效工作流
在现代工作与学习中,可视化工具如流程图、甘特图和思维导图能够极大地提升信息整理与表达的效率。本文将详细介绍如何使用 DeepSeek 生成 Mermaid 文本,结合 Typora 快速生成流程图和甘特图,并通过 Markdown 格式生成思维导图,最终…...
粘贴到Word里的图片显示不全
粘贴到Word里的图片显示不全,可从Word设置、图片本身、软件与系统等方面着手解决,具体方法如下: Word软件设置 经实践发现,图片在word行距的行距出现问题,可以按照如下调整行距进行处理 修改段落行距: 选…...
【C语言】结构体内存对齐问题
1.结构体内存对齐 我们已经基本掌握了结构体的使用了。那我们现在必须得知道结构体在内存中是如何存储的?内存是如何分配的?所以我们得知道如何计算结构体的大小?这就引出了我们今天所要探讨的内容:结构体内存对齐。 1.1 对齐规…...
【蓝桥杯单片机】第十三届省赛第二场
一、真题 二、模块构建 1.编写初始化函数(init.c) void Cls_Peripheral(void); 关闭led led对应的锁存器由Y4C控制关闭蜂鸣器和继电器 2.编写LED函数(led.c) void Led_Disp(unsigned char ucLed); 将ucLed取反的值赋给P0 开启锁存器 关闭锁存…...
类与对象(5)
上一章是类与对象(4)-CSDN博客 深入了构造函数和静态成员,大概讲解了类型转换 最后一章最后一章 友元 在 C 中,友元提供了一种突破类的访问控制(封装)的方式。通过友元,外部的函数或类可以访…...
AI知识架构之数据采集
数据采集 数据格式: 结构化数据:以固定格式和结构存储,如数据库中的表以及 Excel 表格,易于查询和分析。半结构化数据:有一定结构但不如结构化数据严格,XML 常用于数据交换,JSON 在 Web 应用中广泛用于数据传输和存储。非结构化数据:无预定义结构,文本、图像、音频和视…...
细说STM32F407单片机2个ADC使用DMA同步采集各自的1个输入通道的方法
目录 一、示例说明 二、工程配置 1、RCC、DEBUG、CodeGenerator 2、USART6 3、TIM3 (1)Mode (2)参数设置 (3) TRGO (4)ADC1_IN0 1)ADCs_Common_Settings 2&a…...
C# 将非托管Dll嵌入exe中(一种实现方法)
一、环境准备 电脑系统:Windows 10 专业版 20H2 IDE:Microsoft Visual Studio Professional 2022 (64 位) - Current 版本 17.11.4 其他: 二、测试目的 将基于C++创建DLL库,封装到C#生成的exe中。 一般C++创建的库,在C#中使用,都是采用DllImport导入的,且要求库处…...
完美解决:.vmx 配置文件是由 VMware 产品创建,但该产品与此版 VMware Workstation 不兼容
参考文章:该产品与此版 VMware Workstation 不兼容,因此无法使用 问题描述 当尝试使用 VMware Workstation 打开别人的虚拟机时,可能会遇到以下报错: 此问题常见于以下场景: 从其他 VMware 版本(如 ESX…...
使用大语言模型对接OA系统,实现会议室预定功能
随着人工智能技术的不断进步,越来越多的企业开始借助 AI 助手来提高工作效率,尤其是在日常事务的自动化处理中。比如,在许多公司里,会议室的预定是一个常见且频繁的需求,通常需要员工手动检查空闲时间并做出选择。而通…...
Ryu控制器:L2交换功能实现案例
基于 Ryu控制器 在 VM1--OVS--VM2 的简单拓扑中实现流量自动下发(流表动态安装)的完整案例。通过该案例,当VM1与VM2首次通信时,Ryu控制器会动态学习路径并下发流表,后续流量将直接由交换机转发,无需控制器介…...
动手学深度学习2025.2.23-预备知识之-线性代数
3.线性代数 (1)向量维数和张量维数的区别: (2)普通矩阵乘法: 要求左矩阵的列数等于右矩阵的行数 import torch # 创建两个矩阵 A torch.tensor([[1, 2], [3, 4]], dtypetorch.float32) B torch.tensor([[5, 6], [7, 8]], d…...
登录-07.JWT令牌-登录后下发令牌
一.思路 我们首先完成令牌生成。 在响应数据这一块 该响应数据是一个标准的Result结构,其中"data"的值就是一个JWT令牌。因此我们只需要将生成的JWT令牌封装在Result当中然后返回给前端即可。 备注是给前端看的,不用管。以后我们做校验时&…...
机器学习实战(7):聚类算法——发现数据中的隐藏模式
第7集:聚类算法——发现数据中的隐藏模式 在机器学习中,聚类(Clustering) 是一种无监督学习方法,用于发现数据中的隐藏模式或分组。与分类任务不同,聚类不需要标签,而是根据数据的相似性将其划…...
【数据序列化协议】Protocol Buffers
一、为什么需要序列化? 数据跨平台/语言交互: 不同编程语言(如 Java、Python、Go)的数据结构不兼容,序列化提供统一的数据表示。例如:Java 的 HashMap 和 Python 的 dict 需转换为通用格式(如 …...
基于 Python 的电影市场预测分析系统设计与实现(源码 + 文档)
大家好,今天要和大家聊的是一款基于 Python 的“电影市场预测分析”系统的设计与实现。项目源码以及部署相关事宜请联系我,文末附上联系方式。 项目简介 基于 Python 的“电影市场预测分析”系统主要面向以下用户角色:电影制片方、电影发行…...
CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南
文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...
宇树科技,改名了!
提到国内具身智能和机器人领域的代表企业,那宇树科技(Unitree)必须名列其榜。 最近,宇树科技的一项新变动消息在业界引发了不少关注和讨论,即: 宇树向其合作伙伴发布了一封公司名称变更函称,因…...
手机平板能效生态设计指令EU 2023/1670标准解读
手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读,综合法规核心要求、最新修正及企业合规要点: 一、法规背景与目标 生效与强制时间 发布于2023年8月31日(OJ公报&…...
2.3 物理层设备
在这个视频中,我们要学习工作在物理层的两种网络设备,分别是中继器和集线器。首先来看中继器。在计算机网络中两个节点之间,需要通过物理传输媒体或者说物理传输介质进行连接。像同轴电缆、双绞线就是典型的传输介质,假设A节点要给…...
