ZetCode

Spring Boot DataSourceBuilder

最后修改于 2023 年 7 月 29 日

在本文中,我们将展示如何使用 DataSourceBuilder 在命令行 Spring Boot 应用程序中创建数据源。 使用 HikariCP 连接池。

DataSourceBuilder 是一个 Java 便捷类,用于使用常见实现和属性创建数据源。

H2 是一个完全用 Java 编写的开源关系数据库管理系统。它可以嵌入到 Java 应用程序中,也可以在客户端-服务器模式下运行。它易于部署和安装,并且占用资源少。

Spring 是一个用于开发 Java 企业应用程序的 Java 应用程序框架。 它还有助于集成各种企业组件。 Spring Boot 使得创建具有最少设置要求的、由 Spring 驱动的、生产级的应用程序和服务变得容易。

Spring Boot DataSourceBuilder 示例

以下是一个简单的 Spring Boot 控制台应用程序。 它从 H2 内存数据库中检索数据并在终端中显示。 要配置数据源,我们使用 DataSourceBuilder 类。

build.gradle
...
src
├───main
│   ├───java
│   │   └───com
│   │       └───zetcode
│   │           │   Application.java
│   │           │   MyRunner.java
│   │           ├───config
│   │           │       AppConfig.java
│   │           └───model
│   │                   Car.java
│   └───resources
│           application.yml
│           data.sql
│           logback.xml
│           schema.sql
└───test
    └───java

这是项目结构。

build.gradle
plugins {
    id 'org.springframework.boot' version '3.1.1'
    id 'io.spring.dependency-management' version '1.1.0'
    id 'java'
}

group = 'com.zetcode'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-jdbc'
    runtimeOnly 'com.h2database:h2'
}

build.gradle 中,我们声明必要的依赖项。

com/zetcode/model/Car.java
package com.zetcode.model;

import java.util.Objects;

public class Car {

    private Long id;
    private String name;
    private int price;

    public Car() {}

    public Car(Long id, String name, int price) {
        this.id = id;
        this.name = name;
        this.price = price;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Car car = (Car) o;
        return price == car.price &&
                Objects.equals(id, car.id) &&
                Objects.equals(name, car.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name, price);
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("Car{");
        sb.append("id=").append(id);
        sb.append(", name='").append(name).append('\'');
        sb.append(", price=").append(price);
        sb.append('}');
        return sb.toString();
    }
}

这是 Car bean 类。 它包含项目 ID、名称和价格。

resources/schema.sql
CREATE TABLE cars(id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(255), price INT);

此 SQL 脚本创建 cars 表。

resources/data.sql
INSERT INTO cars(name, price) VALUES('Audi', 52642);
INSERT INTO cars(name, price) VALUES('Mercedes', 57127);
INSERT INTO cars(name, price) VALUES('Skoda', 9000);
INSERT INTO cars(name, price) VALUES('Volvo', 29000);
INSERT INTO cars(name, price) VALUES('Bentley', 350000);
INSERT INTO cars(name, price) VALUES('Citroen', 21000);
INSERT INTO cars(name, price) VALUES('Hummer', 41400);
INSERT INTO cars(name, price) VALUES('Volkswagen', 21600);

此脚本用数据填充表。这两个脚本都位于类路径的根目录。

resources/logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/base.xml" />
    <logger name="org.springframework" level="ERROR"/>
    <logger name="com.zetcode" level="DEBUG"/>
    <logger name="com.zaxxer.hikari" level="INFO"/>
</configuration>

logback.xml 文件中,我们配置日志级别。 我们将 Spring 框架的日志级别设置为 ERROR,这样我们的输出就不会被不必要的细节所干扰。

resources/application.yml
spring:
  main:
      banner-mode: "off"
  datasource:
      jdbcUrl: jdbc:h2:mem:testdb

主要的 Spring Boot 配置文件名为 application.yml。 在 datasource 属性中,我们配置数据源。 我们使用内存 H2 数据库。

使用 banner-mode 属性,我们关闭 Spring Boot banner。 Spring Boot 从 jdbcUrl 属性确定数据库。 它通过运行 schema.sqldata.sql SQL 脚本来初始化数据库表。

com/zetcode/config/AppConfig.java
package com.zetcode.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import javax.sql.DataSource;

@Configuration
public class AppConfig {

    @Bean
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }
}

数据源在 AppConfig 中生成。 使用 @ConfigurationProperties 注解,我们将配置外部化到 YAML 文件中。

com/zetcode/MyRunner.java
package com.zetcode;

import com.zetcode.model.Car;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

@Component
public class MyRunner implements CommandLineRunner {
    
    private final JdbcTemplate jdbcTemplate;

    @Autowired
    public MyRunner(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    @Override
    public void run(String... args) {

        var sql = "SELECT * FROM cars";
        var cars = jdbcTemplate.query(sql, 
            BeanPropertyRowMapper.newInstance(Car.class));

        for (Car car : cars) {

            System.out.println(car);
        }
    }
}

MyRunner 执行 SQL 查询并在控制台中显示输出。

private final JdbcTemplate jdbcTemplate;

@Autowired
public MyRunner(JdbcTemplate jdbcTemplate) {
    this.jdbcTemplate = jdbcTemplate;
}

JdbcTemplate 已注入。

var sql = "SELECT * FROM cars";

这是要执行的 SQL。 我们从 cars 表中选择所有汽车。

var cars = jdbcTemplate.query(sql, 
    BeanPropertyRowMapper.newInstance(Car.class));

BeanPropertyRowMapper 将一行转换为指定映射目标类的新实例。

for (Car car: cars) {
    
    System.out.println(car);
}

我们遍历所有汽车对象并将它们打印到控制台。

com/zetcode/Application.java
package com.zetcode;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

`Application` 设置了 Spring Boot 应用程序。

$ ./gradlew bootRun
... 
Car{id=1, name='Audi', price=52642}
Car{id=2, name='Mercedes', price=57127}
Car{id=3, name='Skoda', price=9000}
Car{id=4, name='Volvo', price=29000}
Car{id=5, name='Bentley', price=350000}
Car{id=6, name='Citroen', price=21000}
Car{id=7, name='Hummer', price=41400}
Car{id=8, name='Volkswagen', price=21600}
...

我们运行 Spring Boot 应用程序。 显示了八辆汽车。

在本文中,我们在 Spring Boot 控制台应用程序中使用了 DataSourceBuilder。

作者

我叫 Jan Bodnar,是一位对编程充满热情的程序员,拥有丰富的编程经验。 自 2007 年以来,我一直在撰写编程文章。 迄今为止,我撰写了 1,400 多篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

列出 所有 Spring Boot 教程