Spring Boot 中 JdbcTemplate 处理枚举类型转换 和 减少数据库连接的方法 的详细说明,包含代码示例和关键要点

news2025/4/3 1:13:55

以下是 Spring Boot 中 JdbcTemplate 处理枚举类型转换减少数据库连接的方法 的详细说明,包含代码示例和关键要点:


一、JdbcTemplate 处理枚举类型转换

1. 场景说明

假设数据库存储的是枚举的 Stringint 值,但 Java 实体类使用 enum 类型。例如:

public enum Status {
    ACTIVE, INACTIVE, PENDING
}

public class User {
    private Long id;
    private Status status; // 数据库字段存储为 "ACTIVE" 或 "INACTIVE"
}
2. 方法 1:自定义 RowMapper

手动将数据库字段值转换为枚举:

public class UserRowMapper implements RowMapper<User> {
    @Override
    public User mapRow(ResultSet rs, int rowNum) throws SQLException {
        Status status = Status.valueOf(rs.getString("status")); // 字符串转枚举
        return new User(rs.getLong("id"), status);
    }
}
3. 方法 2:使用 BeanPropertyRowMapper + 自定义转换器

通过 ConversionService 自动转换:

// 配置 ConversionService
@Configuration
public class AppConfig implements WebMvcConfigurer {
    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(String.class, Status.class, 
            source -> Status.valueOf(source));
    }
}

// 使用 BeanPropertyRowMapper
List<User> users = jdbcTemplate.query(
    "SELECT * FROM users",
    BeanPropertyRowMapper.newInstance(User.class)
);
4. 方法 3:使用 @Enumerated 注解(需结合 ORM)

若使用 JPA/Hibernate,可通过 @Enumerated 注解自动转换,但需注意 JdbcTemplate 不直接支持此注解。需配合自定义转换逻辑。


二、减少数据库连接的方法

1. 优化连接池配置

Spring Boot 默认使用 HikariCP 连接池,通过调整参数控制连接数:

# application.properties
# 降低最大连接数(根据实际需求调整)
spring.datasource.hikari.maximum-pool-size=10
# 设置空闲连接超时(单位:毫秒)
spring.datasource.hikari.idle-timeout=30000
# 缩短连接获取超时时间
spring.datasource.hikari.connection-timeout=2000
2. 使用连接池监控

通过 HikariPoolMXBean 监控连接池状态:

@Bean
public HikariPoolMXBean hikariPoolMXBean(DataSource dataSource) {
    return ((HikariDataSource) dataSource).getHikariPoolMXBean();
}

// 示例:获取当前活跃连接数
public void checkConnections() {
    HikariPoolMXBean pool = ...; // 通过注入获取
    System.out.println("Active Connections: " + pool.getActiveConnections());
}
3. 优化 SQL 查询
  • 避免 N+1 查询:使用 JOIN 或批量查询减少数据库调用。
  • 索引优化:确保查询字段有索引,减少查询时间。
  • 分页查询:限制 SELECT 的返回行数(如 LIMIT 100)。
4. 缓存策略
  • 一级缓存:JDBC 驱动自带的查询缓存(如 MySQL 的 query_cache,但需注意并发问题)。
  • 二级缓存:使用 Redis 或 Caffeine 缓存频繁查询的数据:
    @Service
    public class UserService {
        @Autowired
        private JdbcTemplate jdbcTemplate;
        @Autowired
        private CacheManager cacheManager;
    
        public User getUserById(Long id) {
            String key = "user:" + id;
            return (User) cacheManager.getCache("users").get(key, () -> {
                // 查询数据库并缓存结果
                return jdbcTemplate.queryForObject(
                    "SELECT * FROM users WHERE id = ?",
                    new Object[]{id},
                    new UserRowMapper()
                );
            });
        }
    }
    
5. 连接复用与资源管理
  • 使用 try-with-resources:确保 ResultSetConnection 及时关闭:
    try (Connection conn = dataSource.getConnection()) {
        // 执行查询
    } catch (SQLException e) {
        throw new RuntimeException(e);
    }
    
6. 异步查询

通过 CompletableFuture 异步执行查询,释放线程资源:

public CompletableFuture<User> findUserAsync(Long id) {
    return CompletableFuture.supplyAsync(() -> 
        jdbcTemplate.queryForObject(
            "SELECT * FROM users WHERE id = ?",
            new Object[]{id},
            new UserRowMapper()
        ),
        Executors.newFixedThreadPool(5)
    );
}

三、关键对比表格

方法适用场景优点缺点
自定义 RowMapper需要手动控制枚举转换灵活,完全可控代码冗余,需为每个字段编写转换逻辑
BeanPropertyRowMapper列名与属性名一致,使用转换器简单,减少代码量需配置 ConversionService
HikariCP 配置优化控制连接池大小和超时直接减少连接数,降低资源占用需根据负载调整参数,可能影响性能
连接池监控动态调整连接池配置实时监控连接状态,快速发现瓶颈需额外开发监控逻辑
SQL 优化减少查询次数或执行时间显著降低数据库负载需深入分析 SQL 和索引
缓存策略频繁查询且数据不频繁变化减少数据库访问次数需管理缓存失效,可能引入一致性问题
异步查询高并发场景,需释放线程资源提升吞吐量增加复杂度,需处理异步结果

四、注意事项

  1. 枚举转换

    • 确保数据库字段值与枚举常量名称完全一致(或通过转换器处理差异)。
    • 避免在 RowMapper 中抛出未处理的异常,需捕获 SQLException
  2. 连接池配置

    • 根据服务器资源和 QPS 合理设置 maximum-pool-size,避免过大导致数据库负载过高。
    • 监控 activeidle 连接数,及时发现泄漏。
  3. 缓存

    • 对于频繁更新的数据,需设置合理的过期时间或失效策略。
    • 使用分布式缓存(如 Redis)避免单点故障。

五、总结

通过 自定义 RowMapperConversionService 可以优雅地处理枚举类型转换,而 优化连接池配置、SQL 查询和引入缓存 是减少数据库连接的核心策略。根据具体场景选择合适的方法,平衡性能与资源消耗。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2326056.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DataGear 5.3.0 制作支持导出表格数据的数据可视化看板

DataGear 内置表格图表底层采用的是DataTable表格组件&#xff0c;默认并未引入导出数据的JS支持库&#xff0c;如果有导出表格数据需求&#xff0c;则可以在看板中引入导出相关JS支持库&#xff0c;制作具有导出CSV、Excel、PDF功能的表格数据看板。 在新发布的5.3.0版本中&a…

Web网页内嵌 Adobe Pdf Reader 谷歌Chrome在线预览编辑PDF文档

随着数字化办公的普及&#xff0c;PDF文档已成为信息处理的核心载体&#xff0c;虽然桌面端有很多软件可以实现预览编辑PDF文档&#xff0c;而在线在线预览编辑PDF也日益成为一个难题。 作为网页内嵌本地程序的佼佼者——猿大师中间件&#xff0c;之前发布的猿大师办公助手&am…

Sentinel[超详细讲解]-1

定义一系列 规则 &#x1f47a;&#xff0c;对资源进行 保护 &#x1f47a;&#xff0c; 如果违反的了规则&#xff0c;则抛出异常&#xff0c;看是否有fallback兜底处理&#xff0c;如果没有则直接返回异常信息&#x1f60e; 1. 快速入门 1.1 引入 Sentinel 依赖 <depend…

如何让 SQL2API 进化为 Text2API:自然语言生成 API 的深度解析?

在过去的十年里&#xff0c;技术的进步日新月异&#xff0c;尤其是在自动化、人工智能与自然语言处理&#xff08;NLP&#xff09;方面。 随着“低代码”平台的崛起&#xff0c;开发者和非技术人员能够更轻松地构建强大而复杂的应用程序。然而&#xff0c;尽管技术门槛降低了&…

OCCT(2)Windows平台编译OCCT

文章目录 一、Windows平台编译OCCT1、准备环境2、下载源码3、下载第三方库4、使用 CMake 配置5、编译OCCT源码6、运行示例 一、Windows平台编译OCCT 1、准备环境 安装工具&#xff1a; Visual Studio&#xff08;推荐 VS2019/2022&#xff0c;选择 C 桌面开发 组件&#xff0…

【蓝桥杯—单片机】通信总线专项 | 真题整理、解析与拓展 (更新ing...)

通信总线专项 前言SPI第十五届省赛题 UART/RS485/RS232UARTRS485RS232第十三届省赛题小结和拓展&#xff1a;传输方式的分类第十三届省赛 其他相关考点网络传输速率第十五届省赛题第十二届省赛题 前言 在本文中我会把 蓝桥杯单片机赛道 历年真题 中涉及到通信总线的题目整理出…

Uni-app页面信息与元素影响解析

获取窗口信息uni.getWindowInfo {pixelRatio: 3safeArea:{bottom: 778height: 731left: 0right: 375top: 47width: 375}safeAreaInsets: {top: 47, left: 0, right: 0, bottom: 34},screenHeight: 812,screenTop: 0,screenWidth: 375,statusBarHeight: 47,windowBottom: 0,win…

CentOS(最小化)安装之后,快速搭建Docker环境

本文以VMware虚拟机中安装最小化centos完成后开始。 1. 检查网络 打开网卡/启用网卡 执行命令ip a查看当前的网络连接是否正常&#xff1a; 如果得到的结果和我一样&#xff0c;有ens网卡但是没有ip地址&#xff0c;说明网卡未打开 手动启用&#xff1a; nmcli device sta…

【身份证证件OCR识别】批量OCR识别身份证照片复印件图片里的文字信息保存表格或改名字,基于QT和腾讯云api_ocr的实现方式

项目背景 在许多业务场景中,需要处理大量身份证照片复印件,手动输入其中的文字信息效率低下且容易出错。利用 OCR(光学字符识别)技术可以自动识别身份证图片中的文字信息,结合 QT 构建图形用户界面,方便用户操作,同时使用腾讯 OCR API 能够保证较高的识别准确率。 界面…

IP属地和发作品的地址不一样吗

在当今这个数字化时代&#xff0c;互联网已经成为人们日常生活不可或缺的一部分。随着各大社交平台功能的不断完善&#xff0c;一个新功能——IP属地显示&#xff0c;逐渐走进大众视野。这一功能在微博、抖音、快手等各大平台上得到广泛应用&#xff0c;旨在帮助公众识别虚假信…

Redis - 概述

目录 ​编辑 一、什么是redis 二、redis能做什么&#xff08;有什么特点&#xff09;&#xff1f; 三、redis有什么优势 四、Redis与其他key-value存储有什么不同 五、Redis命令 六、Redis数据结构 1、基础数据结构 2、高级数据结构 一、什么是redis 1、redis&#x…

vue3 根据城市名称计算城市之间的距离

<template><div class"distance-calculator"><h1>城市距离计算器</h1><!-- 城市输入框 --><div class"input-group"><inputv-model"city1"placeholder"请输入第一个城市"keyup.enter"cal…

html 列表循环滚动,动态初始化字段数据

html <div class"layui-row"><div class"layui-col-md4"><div class"boxall"><div class"alltitle">超时菜品排行</div><div class"marquee-container"><div class"scroll-…

QT基础:安装与简介

QT初级 1、简介1.1 安装1.2 设置1.3 在VS中配置Qt1.3 帮助文档 2、Qt项目2.1 创建项目2.1 项目文件2.2 Qt中的窗口类窗口显示 2.3 坐标体系2.4 内存回收 1、简介 QT是一个跨平台的C应用程序开发框架。几乎支持所有的平台, 可用于桌面程序开发以及嵌入式开发。 Qt是标准 C 的扩…

WEB安全-HTTPS

1 需求 结合Wireshark抓包实战&#xff0c;图文详解TCP三次握手及四次挥手原理&#xff08;附下载&#xff09; 结合Wireshark抓包分析&#xff0c;沉浸式体验HTTP请求的一次完整交互过程 https://mp.weixin.qq.com/s/f3LmUEtjIuLjkyjxJj7ebA 一文彻底了解DNS协议工作原理&…

【宇宙回响】从Canvas到MySQL:飞机大战的全栈交响曲【附演示视频与源码】

🌟 这是星际大战系列的第三篇,感谢一路以来支持和关注这个项目的每一位朋友! 💡 文章力求严谨,但难免有疏漏之处,欢迎各位朋友指出,让我们一起在交流中进步。 🎁 项目代码、文档和相关资源都可以免费获取,希望能帮助到更多对游戏开发感兴趣的朋友。 💌 如果您有任…

git push origin masterremote: [session-bd46a49f] The token username invalid

参考:如何把项目上传到Gitee&#xff08;保姆级教程&#xff09;_gitee上传项目-CSDN博客 1 新建仓库 username可以是登录账号的邮箱地址也可以是用户名 password可以是登录账号的密码也可以是私人令牌 2 创建分支 3 初始化 dev是你新建的分支 创建并切换分支 git init g…

基于MCU实现的电机转速精确控制方案:软件设计与实现

本文将详细介绍一篇基于微控制器&#xff08;MCU&#xff09;的电机转速精确控制的软件方案。通过采样PWM信号控制和ADC采样技术&#xff0c;结合PID闭环控制算法&#xff0c;实现了电机转速的高效、稳定调节。以下是软件方案流程图&#xff0c;下文将对其进行展开讲解。 原图太…

【模拟CMOS集成电路笔记】轨到轨运放(Rail to Rail)基础(附带实例:基于1:3电流镜的轨到轨输入运放)

【模拟CMOS集成电路笔记】轨到轨运放&#xff08;Rail to Rail&#xff09;基础 0前言1 简介1.1轨到轨输入级(1)互补差分对&#xff1a;(2)输入范围切换&#xff1a; 1.2轨到轨输出级(1)推挽输出&#xff1a;(1)输出级偏置&#xff1a; 2轨到轨输入运放2.1基于电流倍增实现恒定…

【零基础入门unity游戏开发——通用篇】图片相关设置

考虑到每个人基础可能不一样,且并不是所有人都有同时做2D、3D开发的需求,所以我把 【零基础入门unity游戏开发】 分为成了C#篇、unity通用篇、unity3D篇、unity2D篇。 【C#篇】:主要讲解C#的基础语法,包括变量、数据类型、运算符、流程控制、面向对象等,适合没有编程基础的…