首页 > 其他分享 >从 spring-boot-starter-jdbc 到 DataSource

从 spring-boot-starter-jdbc 到 DataSource

时间:2024-12-18 22:09:38浏览次数:3  
标签:jdbc spring boot properties dataSource class DataSource

JDBC 是什么

JDBC 是 Java DataBase Connectivity 的缩写,是由一组用 Java 语言编写的类和接口,用于在 Java 应用程序中与数据库进行交互。

JDBC 只是一套标准规范,具体的实现由各个数据库厂商去实现。对开发者来说其屏蔽了不同数据库之间的区别,可以使用相同的方式(Java API)去操作不同的数据库。不同数据库厂商对 JDBC 的实现就是常说的数据库驱动。如 mysql-connector-java 是连接 MySQL 数据库的驱动。

如何使用 JDBC

大致步骤:

  1. 加载驱动
  2. 获取连接
  3. 执行 SQL
  4. 处理结果
  5. 释放资源

如果你使用 Maven,可以在 pom.xml 文件中添加驱动依赖:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.32</version>
</dependency>

然后如下使用 JDBC:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class JdbcExample {
    public static void main(String[] args) {
        // 数据库 URL
        String url = "jdbc:mysql://localhost:3306/test";
        // 数据库用户名和密码
        String user = "root";
        String password = "123456";

        // 声明连接和其他对象
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;

        try {
            // 1. 加载 JDBC 驱动
            Class.forName("com.mysql.cj.jdbc.Driver");

            // 2. 创建连接
            connection = DriverManager.getConnection(url, user, password);

            // 3. 创建 Statement 对象
            statement = connection.createStatement();

            // 4. 执行查询
            String sql = "SELECT * FROM user";
            resultSet = statement.executeQuery(sql);

            // 5. 处理结果集
            while (resultSet.next()) {
                int id = resultSet.getInt("id");
                String name = resultSet.getString("name");
                System.out.println("ID: " + id + ", Name: " + name);
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 6. 关闭资源
            try {
                if (resultSet != null) resultSet.close();
                if (statement != null) statement.close();
                if (connection != null) connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

DataSource 接口

DataSource 接口(javax.sql.DataSource)是 JDBC 2.0 引入的,用于表示数据库连接工厂。功能上,可以把 DriverManager 看作是 JDBC 官方提供的 DataSource 实现(虽然实际上 DriverManager 并没有实现 DataSource 接口)。

DataSource 的常见实现有 DBCP、C3P0、HikariCP、Druid 等,这些实现通常使用了池化技术来提高连接利用率。

spring-boot-starter-jdbc 数据源配置

spring-boot-starter-jdbc 是 Spring Boot 提供的用于简化 JDBC 操作的 starter。主要有三个功能:

  1. 提供了 DataSource 的自动配置
  2. 提供了 JdbcTemplate 等工具类来简化 JDBC 操作
  3. 提供了事务管理

下面主要关注数据源的自动配置。

在项目中引入 spring-boot-starter-jdbc 后,会自动配置一个 DataSource 的 Bean,并提供一个 JdbcTemplate 的 Bean:

@Slf4j
@Component
public class Init implements CommandLineRunner {

    @Resource
    private DataSource dataSource;

    @Resource
    private JdbcTemplate jdbcTemplate;

    @Override
    public void run(String... args) {
        log.info(dataSource.getClass().getName());
        log.info(jdbcTemplate.getClass().getName());
    }

}
com.zaxxer.hikari.HikariDataSource
org.springframework.jdbc.core.JdbcTemplate

可以看到,DataSource 的默认实现类是 HikariDataSource。也就是 Spring Boot 默认使用了 HikariCP 作为连接池。

进入 org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,其中的 PooledDataSourceConfiguration 会根据配置文件中的 spring.datasource.type 属性来决定使用哪个 DataSource 实现类(注意 @Import 注解):

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@ConditionalOnMissingBean(type = "io.r2dbc.spi.ConnectionFactory")
@AutoConfigureBefore(SqlInitializationAutoConfiguration.class)
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({ DataSourcePoolMetadataProvidersConfiguration.class,
		DataSourceInitializationConfiguration.InitializationSpecificCredentialsDataSourceInitializationConfiguration.class,
		DataSourceInitializationConfiguration.SharedCredentialsDataSourceInitializationConfiguration.class })
public class DataSourceAutoConfiguration {

	// ...

	@Configuration(proxyBeanMethods = false)
	@Conditional(PooledDataSourceCondition.class)
	@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
	@Import({ DataSourceConfiguration.Hikari.class, DataSourceConfiguration.Tomcat.class,
			DataSourceConfiguration.Dbcp2.class, DataSourceConfiguration.OracleUcp.class,
			DataSourceConfiguration.Generic.class, DataSourceJmxConfiguration.class })
	protected static class PooledDataSourceConfiguration {

	}

	// ...

}

比如打开 DataSourceConfiguration.Hikari 可以看到:

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(HikariDataSource.class)
@ConditionalOnMissingBean(DataSource.class)
@ConditionalOnProperty(name = "spring.datasource.type", havingValue = "com.zaxxer.hikari.HikariDataSource",
    matchIfMissing = true)
static class Hikari {

  @Bean
  @ConfigurationProperties(prefix = "spring.datasource.hikari")
  HikariDataSource dataSource(DataSourceProperties properties) {
    HikariDataSource dataSource = createDataSource(properties, HikariDataSource.class);
    if (StringUtils.hasText(properties.getName())) {
      dataSource.setPoolName(properties.getName());
    }
    return dataSource;
  }

}

spring.datasource.type没有配置的情况下,默认会使用 HikariDataSource。因为 Spring Boot 默认引入了 HikariCP,而没有引入其他连接池的依赖比如 DBCP2,所以会使用 HikariDataSource。

再看createDataSource方法,该方法会根据配置文件中配置的 url 等属性来创建 HikariDataSource。

protected static <T> T createDataSource(DataSourceProperties properties, Class<? extends DataSource> type) {
  return (T) properties.initializeDataSourceBuilder().type(type).build();
}
public DataSourceBuilder<?> initializeDataSourceBuilder() {
  return DataSourceBuilder.create(getClassLoader()).type(getType()).driverClassName(determineDriverClassName())
      .url(determineUrl()).username(determineUsername()).password(determinePassword());
}

要切换其他连接池,比如 Druid,可以引入 Druid 的依赖:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.9</version>
</dependency>

然后在配置文件中指定 spring.datasource.type 为 com.alibaba.druid.pool.DruidDataSource:

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource

如果项目中使用了 [dynamic-datasource][dynamic-datasource],进入其自动配置文件 DynamicDataSourceAutoConfiguration,可以看到其会在容器中注册 DynamicRoutingDataSource:

@Bean
@ConditionalOnMissingBean
public DataSource dataSource() {
    DynamicRoutingDataSource dataSource = new DynamicRoutingDataSource();
    dataSource.setPrimary(properties.getPrimary());
    dataSource.setStrict(properties.getStrict());
    dataSource.setStrategy(properties.getStrategy());
    dataSource.setP6spy(properties.getP6spy());
    dataSource.setSeata(properties.getSeata());
    return dataSource;
}

DynamicRoutingDataSource 继承自 AbstractRoutingDataSource,并实现了 DataSource 接口,其能够结合 @DS 注解,根据不同的数据源名称来切换不同的数据源。

参考:从 jdbc 到 spring-boot-starter-jdbc什么是 DataSource?什么又是 DruidDataSource?SpringBoot 2.X 集成 jdbc 自动配置原理探究

标签:jdbc,spring,boot,properties,dataSource,class,DataSource
From: https://www.cnblogs.com/Higurashi-kagome/p/18615936

相关文章

  • 【论文投稿】Spring Boot 开发全攻略:从入门到精通
    2025年计算生物学与系统生物学学术研讨会(CBSB2025)_艾思科蓝_学术一站式服务平台 更多学术会议请看: https://ais.cn/u/nuyAF3目录一、SpringBoot简介与优势二、开发环境搭建三、创建SpringBoot项目四、项目结构剖析五、控制器开发六、服务层设计七、数据访问......
  • 基于java的SpringBoot/SSM+Vue+uniapp的大学校园防疫与服务系统的详细设计和实现(源码
    文章目录前言详细视频演示具体实现截图技术栈后端框架SpringBoot前端框架Vue持久层框架MyBaitsPlus系统测试系统测试目的系统功能测试系统测试结论为什么选择我代码参考数据库参考源码获取前言......
  • springboot毕设 疫情监控系统 程序+论文
    本系统(程序+源码)带文档lw万字以上文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着互联网技术的飞速发展和数字媒体的普及,音乐已经成为人们日常生活中不可或缺的一部分。音乐网站作为数字音乐传播的重要平台,不仅提供了丰富的音乐......
  • springboot毕设 音乐网站 程序+论文
    本系统(程序+源码)带文档lw万字以上文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着互联网技术的飞速发展和数字媒体的普及,音乐已经成为人们日常生活中不可或缺的一部分。音乐网站作为数字音乐传播的重要平台,不仅提供了丰富的音乐......
  • Java框架 —— SpringMVC
    MVC分层MVC:ModelViewController(模型-视图-控制器)模型(Model):处理数据逻辑的部分;在web应用中,他通常包含与数据库交互的代码,负责数据的存储、检索和更新视图(View):将数据渲染为用户界面,视图只展示页面,不包含业务逻辑控制器(Controller):模型和视图之间的协调者,它接收用户的......
  • Spring Boot教程之三十二:自定义 Jackson ObjectMapper
    SpringBoot–自定义JacksonObjectMapper当使用JSON格式时,SpringBoot将使用ObjectMapper实例来序列化响应并反序列化请求。在本文中,我们将介绍配置序列化和反序列化选项的最常用方法。让我们来看看默认配置。默认情况下,SpringBoot配置如下:禁用MapperFeature.DE......
  • Java基于springboot+vue的摄影设备租赁管理系统
    收藏关注不迷路!!......
  • 基于SpringBoot的二手车交易系统的设计与实现(源码+SQL脚本+LW+部署讲解等)
    专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。主要内容:免费功能设计、开题报告、任务书、中......
  • springboot毕设 农产品交易平台app程序+论文
    系统程序文件列表开题报告内容研究背景随着信息技术的飞速发展和移动互联网的普及,电子商务已经成为现代商业的重要组成部分。在农产品领域,传统的销售模式面临着信息不对称、流通效率低、交易成本高等诸多挑战。为了应对这些挑战,构建一个农产品交易平台APP显得尤为重要。该......
  • springboot毕设 垃圾分类回收系统的设计与实现程序+论文
    系统程序文件列表开题报告内容研究背景随着城市化进程的加速,垃圾产生量急剧增加,垃圾分类成为解决环境问题、促进资源循环利用的重要手段。然而,当前垃圾分类工作仍面临诸多挑战,如公众分类意识不足、分类知识缺乏、分类设施不完善等。因此,设计并实现一个高效、便捷的垃圾分类......