Spring Boot SQL数据库全攻略

📚 总览:Spring Boot 如何与 SQL 数据库交互?

Spring Boot 提供了多层次的支持来操作数据库:

层次 技术 特点
最底层 JdbcTemplate 直接执行 SQL,轻量高效
中间层 JPA + Hibernate 面向对象映射,自动建表
高层抽象 Spring Data JPA / JDBC / R2DBC 接口即实现,方法名生成 SQL
响应式 R2DBC 非阻塞、异步数据库访问
工具支持 H2 Console、jOOQ 可视化调试、类型安全查询

🔧 5.11.1 配置数据源(DataSource)

✅ 什么是 DataSource

Java 标准接口 javax.sql.DataSource,用于获取数据库连接。Spring Boot 会自动帮你创建这个对象。

📦 内嵌数据库(Embedded Database)

开发时很方便,比如 H2、HSQL、Derby,数据在内存中,重启就没了

  • Spring Boot 能自动配置 H2、HSQL、Derby。
  • 只需添加依赖即可,不需要写 URL
  • 示例:
xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>org.hsqldb</groupId>
    <artifactId>hsqldb</artifactId>
    <scope>runtime</scope>
</dependency>

⚠️ 注意:测试中多个上下文可能共用一个内嵌数据库,若要隔离,设置:

properties 复制代码
spring.datasource.generate-unique-name=true

❗ 关闭自动关闭(防止 Spring 还没用完就被关了):

  • H2: DB_CLOSE_ON_EXIT=FALSE
  • HSQL: 不要用 shutdown=true

🏭 生产环境数据库(Pooling DataSource)

Spring Boot 自动选择连接池(按优先级):

  1. HikariCP ✅(首选,性能最好)
  2. Tomcat JDBC Pool
  3. Commons DBCP2

只要引入 spring-boot-starter-jdbcspring-boot-starter-data-jpa,就会自动带上 HikariCP。

你可以手动指定连接池类型:

properties 复制代码
spring.datasource.type=com.zaxxer.hikari.HikariDataSource

💡 如果你自己定义了 @Bean DataSource,Spring Boot 就不再自动配置。


🛠 配置 DataSource 的方式

通过 application.properties 设置:

properties 复制代码
spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

✅ 提示:driver-class-name 通常可以省略,Spring Boot 会根据 URL 自动推断(如 jdbc:mysql://... → MySQL 驱动)。


⚙️ 自定义连接池参数(以 Hikari 为例)

properties 复制代码
# Hikari 特有配置
spring.datasource.hikari.maximum-pool-size=20
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.idle-timeout=30000

# Tomcat Pool 示例(文档中的例子)
spring.datasource.tomcat.max-wait=10000
spring.datasource.tomcat.max-active=50
spring.datasource.tomcat.test-on-borrow=true

🌐 使用 JNDI 数据源(部署到应用服务器时)

如果你把应用部署到 WebLogic、JBoss 等容器,数据库由容器管理,可通过 JNDI 获取:

properties 复制代码
spring.datasource.jndi-name=java:jboss/datasources/customers

此时就不需要 url/username/password


🛠 5.11.2 使用 JdbcTemplate

Spring 的 JdbcTemplate 是最基础的 JDBC 操作工具,Spring Boot 会自动配置它。

✅ 使用方法

java 复制代码
@Component
public class MyBean {

    private final JdbcTemplate jdbcTemplate;

    public MyBean(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public List<String> getAllUsernames() {
        return jdbcTemplate.queryForList(
            "SELECT username FROM users", String.class);
    }
}

✅ 构造器注入(推荐),无需 @Autowired(Spring 4.3+ 自动装配)

🎛 自定义模板行为

properties 复制代码
spring.jdbc.template.max-rows=500

🧱 5.11.3 JPA 和 Spring Data JPA

📌 什么是 JPA?

Java Persistence API,标准 ORM 技术,把 Java 对象"映射"成数据库表。

常用实现:Hibernate

🚀 快速开始依赖

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

包含:

  • Hibernate(JPA 实现)
  • Spring Data JPA(简化 Repository)
  • Spring ORM(核心支持)

🏗 实体类(Entity Classes)

以前要用 persistence.xml,现在 Spring Boot 自动扫描 @Entity 类。

java 复制代码
@Entity
public class City implements Serializable {
    @Id
    @GeneratedValue
    private Long id;

    @Column(nullable = false)
    private String name;
    private String state;

    protected City() {} // JPA 要求无参构造

    public City(String name, String state) {
        this.name = name;
        this.state = state;
    }
    // getter/setter...
}

✅ 默认扫描主类所在包及其子包。可用 @EntityScan("com.example.domain") 修改扫描路径。


🗃 Spring Data JPA Repositories

你只需定义接口,Spring Data 自动实现!

java 复制代码
public interface CityRepository extends Repository<City, Long> {
    Page<City> findAll(Pageable pageable);
    City findByNameAndStateAllIgnoringCase(String name, String state);
}
  • 方法名自动解析成 SQL 查询。
  • find...By... 是命名规则。
  • 支持分页 Pageable

✅ 推荐继承 CrudRepositoryJpaRepository,功能更全(增删改查、批量等)。

java 复制代码
public interface CityRepository extends JpaRepository<City, Long> {
    // 自动有 save(), findById(), deleteById(), findAll()...
}

🔁 启动模式(Bootstrap Mode)

控制 Repository 初始化时机:

properties 复制代码
# 默认:启动时初始化
spring.data.jpa.repositories.bootstrap-mode=default

# 延迟初始化(适合微服务注册前不连 DB)
spring.data.jpa.repositories.bootstrap-mode=deferred

# 懒加载
spring.data.jpa.repositories.bootstrap-mode=lazy

⚠️ 延迟/懒加载时,确保不要在启动初期访问数据库。


🔧 创建/删除数据库表(DDL)

默认只在使用内嵌数据库时自动建表。

想手动控制建表行为,使用:

properties 复制代码
# 常见选项:
spring.jpa.hibernate.ddl-auto=none     # 不做任何操作(生产推荐)
spring.jpa.hibernate.ddl-auto=create   # 启动时创建表(丢失旧数据)
spring.jpa.hibernate.ddl-auto=create-drop # 启动创建,关闭删除
spring.jpa.hibernate.ddl-auto=update   # 更新表结构(慎用)
spring.jpa.hibernate.ddl-auto=validate # 校验实体与表是否一致

⚠️ 生产环境必须设为 nonevalidate,避免误删数据!

也可以设置其他 Hibernate 属性:

properties 复制代码
spring.jpa.properties.hibernate.globally_quoted_identifiers=true

👁 Open EntityManager in View

Web 项目中,默认开启 OpenEntityManagerInViewInterceptor,允许在视图层(如 Thymeleaf)进行懒加载。

但可能导致 N+1 查询问题或事务过长。

关闭它:

properties 复制代码
spring.jpa.open-in-view=false

✅ 推荐在生产环境中关闭,避免性能问题。


🔄 5.11.4 Spring Data JDBC

轻量级 ORM,比 JPA 简单,适合简单场景。

  • 不支持延迟加载、缓存等复杂特性。
  • 但更直观,性能好。

引入依赖即可:

xml 复制代码
<dependency>
    <groupId>spring-boot-starter-data-jdbc</groupId>
    <artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>

用法类似 Spring Data JPA:

java 复制代码
public interface CityRepository extends CrudRepository<City, Long> {
    List<City> findByState(String state);
}

✅ 自动根据方法名生成 SQL。


🔍 5.11.5 使用 H2 Web 控制台

开发时非常有用的数据库可视化工具。

✅ 开启条件:

  1. 是 Web 应用(有 spring-web)
  2. h2 依赖
  3. 启用了 spring-boot-devtools

满足后访问:http://localhost:8080/h2-console

⚠️ 默认路径 /h2-console,可修改:

properties 复制代码
spring.h2.console.path=/console

❗ 绝对不要在生产环境开启!

properties 复制代码
spring.h2.console.enabled=true # 仅开发用

🧩 5.11.6 使用 jOOQ(类型安全 SQL)

jOOQ 是一个生成 Java 代码的工具,让你用链式语法写 SQL,且编译时检查错误。

✅ 使用步骤:

  1. 添加依赖:
xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jooq</artifactId>
</dependency>
  1. jooq-codegen-maven 插件生成代码(根据数据库表生成 Java 类)

  2. 使用 DSLContext 构建类型安全查询:

java 复制代码
@Autowired
private DSLContext dsl;

public List<Author> findAuthorsBornAfter1980() {
    return dsl.selectFrom(AUTHOR)
              .where(AUTHOR.DATE_OF_BIRTH.greaterThan(Date.valueOf("1980-01-01")))
              .fetchInto(Author.class);
}

✅ 类型安全、IDE 提示、防 SQL 注入。


🌐 SQL 方言(Dialect)

properties 复制代码
spring.jooq.sql-dialect=POSTGRES

如果不设置,Spring Boot 自动检测。


🛠 高级定制 jOOQ 行为

可以注入以下组件进行定制:

  • ConnectionProvider
  • TransactionProvider
  • Settings
  • ExecuteListenerProvider(监听 SQL 执行)

⚡ 5.11.7 使用 R2DBC(响应式数据库)

用于响应式编程(Reactor),非阻塞 IO。

✅ 适用场景:

  • 高并发、低延迟系统
  • 使用 WebFlux 的项目

📦 依赖:

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-r2dbc</artifactId>
</dependency>

🛠 配置:

properties 复制代码
spring.r2dbc.url=r2dbc:postgresql://localhost/test
spring.r2dbc.username=dbuser
spring.r2dbc.password=dbpass

✅ 不需要 driver-class-name,R2DBC 自动发现驱动。


🧩 内嵌数据库支持

xml 复制代码
<dependency>
    <groupId>io.r2dbc</groupId>
    <artifactId>r2dbc-h2</artifactId>
    <scope>runtime</scope>
</dependency>

自动配置,无需 URL。


🧰 使用 DatabaseClient

Spring Data 提供的响应式数据库客户端:

java 复制代码
@Autowired
private DatabaseClient client;

public Mono<City> findCity(String name) {
    return client.sql("SELECT * FROM city WHERE name = $1")
                 .bind(0, name)
                 .fetch()
                 .one();
}

🗃 Spring Data R2DBC Repositories

和 JPA 类似,但返回 Mono<T>Flux<T>

java 复制代码
public interface CityRepository extends ReactiveCrudRepository<City, Long> {
    Mono<City> findByNameAndStateAllIgnoringCase(String name, String state);
}

✅ 方法名自动解析成查询,支持响应式流。


✅ 总结:如何选择技术?

需求 推荐技术
简单 CRUD,快速开发 ✅ Spring Data JPA
高性能、轻量级 ✅ JdbcTemplate 或 Spring Data JDBC
类型安全 SQL 查询 ✅ jOOQ
响应式系统(WebFlux) ✅ R2DBC + Spring Data R2DBC
开发调试 ✅ H2 + H2 Console
复杂 SQL、报表 ✅ JdbcTemplate + 原生 SQL 或 jOOQ

📌 最佳实践建议

  1. 生产环境不要用 ddl-auto=create-drop
  2. 关闭 open-in-view,避免懒加载陷阱
  3. H2 Console 仅开发启用
  4. 优先使用构造器注入
  5. Repository 接口继承 JpaRepository 而不是 Repository
  6. R2DBC 和 JDBC 不要混用在一个应用中(除非明确知道风险)

如果你想深入了解某一部分(比如"如何用 jOOQ 生成代码"或"R2DBC 如何做事务"),我可以继续展开讲解。是否需要?

相关推荐
EndingCoder5 小时前
MongoDB基础与Mongoose ODM
服务器·javascript·数据库·mongodb·中间件·node.js
赋能大师兄5 小时前
SQLITE数据库完成数据增删改查
数据库·sqlite
一个天蝎座 白勺 程序猿6 小时前
深度解析:通过ADO.NET驱动Kdbndp高效连接与操作Kingbase数据库
数据库·.net·wpf·kingbase·金仓数据库
AI科技星6 小时前
垂直原理:宇宙的沉默法则与万物运动的终极源头
android·服务器·数据结构·数据库·人工智能
Warren986 小时前
复习MySQL
数据库·windows·tcp/ip·mysql·ubuntu·ssh·ansible
黑金IT6 小时前
3D虚拟人模型转换的完整指南
服务器·数据库·3d
是梦终空6 小时前
计算机毕业设计241—基于Java+Springboot+vue的爱心公益服务系统(源代码+数据库+11000字文档)
java·spring boot·vue·毕业设计·课程设计·毕业论文·爱心公益系统
凌~风6 小时前
数据库原理实验报告:在ider里搭建mysql数据库
数据库·mysql·实验报告
keke_俩个科6 小时前
ShardingSphere分库分表基础配置与使用说明
java·数据库·分布式·spring