数据库操作核心类宜用静态内部类实现单例,仅持线程安全的datasource而非connection,配合配置加载与shutdown清理,确保高效、安全、可维护。

数据库操作核心类通常设计为单例,主要是为了统一管理连接池、避免重复创建资源、保证线程安全和配置一致性。但要注意:单例本身不解决数据库并发问题,真正关键的是底层连接池(如 HikariCP)和连接的正确使用方式。
推荐方式:懒汉式 + 双重检查锁(线程安全且延迟加载)
适用于需要控制初始化时机、且希望避免类加载时就创建实例的场景:
- 用 private static volatile 修饰实例,防止指令重排序导致未初始化完成就被其他线程访问
- 构造方法私有,禁止外部 new
- 提供 public static getInstance() 方法,内部加 synchronized 块 + 外层判空
- 在 getInstance() 中初始化 DataSource(如 HikariDataSource),并封装常用模板方法(query/update/execute)
更简洁可靠的方式:静态内部类(推荐)
利用 JVM 类加载机制保证线程安全,无同步开销,也支持延迟加载:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 定义一个 private static class Holder { static final DatabaseCore INSTANCE = new DatabaseCore(); }
- getInstance() 直接 return Holder.INSTANCE
- 首次调用 getInstance() 时才触发 Holder 类加载,从而初始化实例
- 天然线程安全,写法干净,JVM 层面保障
注意:单例 ≠ 全局共享 Connection
很多初学者误以为单例类里存一个 Connection 就行,这是严重错误:
- Connection 不是线程安全的,不能多线程共用
- 应通过 DataSource 获取连接(每次 query 前 getConnection(),用完 close() 或 try-with-resources)
- 单例中只持有一个 DataSource 实例(它是线程安全的),而不是 Connection
- 可封装 JdbcTemplate 类似逻辑:每次操作都申请新连接,自动释放
补充建议:配合配置与生命周期管理
让单例更健壮实用:
- 支持从 properties/yml 文件或环境变量加载数据库配置
- 提供 shutdown() 方法,显式关闭 DataSource(释放连接池资源)
- 考虑实现 AutoCloseable,便于在应用关闭时统一清理
- 避免在单例中硬编码 SQL,应交由 DAO 层或 Mapper 负责
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










