深入讲解 Spring Boot 自动配置中的数据源配置
为了更好地理解 Spring Boot 中的自动配置机制,我们以数据源配置机制为例,按照以下顺序进行讲解:
- 不使用任何框架来连接数据源的方式
- 使用 Spring MVC 连接数据源的方式
- 使用 Spring Boot 自动配置连接数据源的方式
每个部分都会配有实例代码,并对代码进行详细的解释。
1. 不使用任何框架来连接数据源的方式
1.1 实例代码
java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class DataSourceExample {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
// 1. 加载数据库驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 2. 创建数据库连接
String url = "jdbc:mysql://localhost:3306/mydb";
String user = "root";
String password = "secret";
connection = DriverManager.getConnection(url, user, password);
// 3. 创建 PreparedStatement 对象
String sql = "SELECT id, name, email FROM users WHERE id = ?";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1, 1); // 设置参数
// 4. 执行查询
resultSet = preparedStatement.executeQuery();
// 5. 处理查询结果
while (resultSet.next()) {
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
String email = resultSet.getString("email");
System.out.println("ID: " + id + ", Name: " + name + ", Email: " + email);
}
} catch (ClassNotFoundException e) {
System.out.println("MySQL JDBC Driver not found.");
e.printStackTrace();
} catch (SQLException e) {
System.out.println("Connection failed or query execution failed!");
e.printStackTrace();
} finally {
// 6. 关闭资源
try {
if (resultSet != null) resultSet.close();
if (preparedStatement != null) preparedStatement.close();
if (connection != null) connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
1.2 代码解释
-
加载数据库驱动:
javaClass.forName("com.mysql.cj.jdbc.Driver");
这行代码用于加载 MySQL 的 JDBC 驱动类。
-
创建数据库连接:
javaString url = "jdbc:mysql://localhost:3306/mydb"; String user = "root"; String password = "secret"; connection = DriverManager.getConnection(url, user, password);
这里我们定义了数据库的 URL、用户名和密码,然后使用
DriverManager.getConnection
方法创建数据库连接。 -
创建
PreparedStatement
对象:javaString sql = "SELECT id, name, email FROM users WHERE id = ?"; preparedStatement = connection.prepareStatement(sql); preparedStatement.setInt(1, 1); // 设置参数
使用
connection.prepareStatement(sql)
方法创建一个PreparedStatement
对象,并设置 SQL 查询语句中的参数。 -
执行查询:
javaresultSet = preparedStatement.executeQuery();
使用
preparedStatement.executeQuery()
方法执行查询,返回一个ResultSet
对象。 -
处理查询结果:
javawhile (resultSet.next()) { int id = resultSet.getInt("id"); String name = resultSet.getString("name"); String email = resultSet.getString("email"); System.out.println("ID: " + id + ", Name: " + name + ", Email: " + email); }
使用
resultSet.next()
方法遍历查询结果集,使用resultSet.getInt
和resultSet.getString
方法获取每一行的数据。 -
关闭资源:
javatry { if (resultSet != null) resultSet.close(); if (preparedStatement != null) preparedStatement.close(); if (connection != null) connection.close(); } catch (SQLException e) { e.printStackTrace(); }
最后,确保关闭
ResultSet
、PreparedStatement
和Connection
对象,以释放资源。
2. 使用 Spring MVC 连接数据源的方式
2.1 实例代码
首先,我们需要在 pom.xml
中添加 Spring 和 JDBC 的依赖:
xml
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.10</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.10</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency>
</dependencies>
然后,创建一个配置类来配置数据源:
java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import javax.sql.DataSource;
@Configuration
public class DataSourceConfig {
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/mydb");
dataSource.setUsername("root");
dataSource.setPassword("secret");
return dataSource;
}
}
接下来,创建一个简单的 DAO 类来使用数据源:
java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
@Repository
public class UserDao {
private final JdbcTemplate jdbcTemplate;
@Autowired
public UserDao(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
public void createUser(String name, String email) {
String sql = "INSERT INTO users (name, email) VALUES (?, ?)";
jdbcTemplate.update(sql, name, email);
}
}
最后,创建一个 Spring 应用上下文来测试数据源配置:
java
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class SpringMVCExample {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(DataSourceConfig.class);
UserDao userDao = context.getBean(UserDao.class);
userDao.createUser("John Doe", "john.doe@example.com");
System.out.println("User created successfully!");
}
}
2.2 代码解释
-
配置数据源:
java@Bean public DataSource dataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/mydb"); dataSource.setUsername("root"); dataSource.setPassword("secret"); return dataSource; }
在
DataSourceConfig
类中,我们定义了一个dataSource
Bean,使用DriverManagerDataSource
来配置数据库连接信息。 -
创建 DAO 类:
java@Repository public class UserDao { private final JdbcTemplate jdbcTemplate; @Autowired public UserDao(DataSource dataSource) { this.jdbcTemplate = new JdbcTemplate(dataSource); } public void createUser(String name, String email) { String sql = "INSERT INTO users (name, email) VALUES (?, ?)"; jdbcTemplate.update(sql, name, email); } }
UserDao
类使用@Repository
注解标记为 Spring 的 DAO 组件。通过构造函数注入DataSource
,并使用JdbcTemplate
执行 SQL 操作。 -
创建 Spring 应用上下文:
javaApplicationContext context = new AnnotationConfigApplicationContext(DataSourceConfig.class); UserDao userDao = context.getBean(UserDao.class); userDao.createUser("John Doe", "john.doe@example.com");
在
SpringMVCExample
类中,我们创建了一个 Spring 应用上下文,并获取UserDao
Bean 来执行数据库操作。
3. 使用 Spring Boot 自动配置连接数据源的方式
3.1 实例代码
首先,在 pom.xml
中添加 Spring Boot 和 JDBC 的依赖:
xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
然后,在 application.yaml
中配置数据源:
yaml
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb
username: root
password: secret
driver-class-name: com.mysql.cj.jdbc.Driver
接下来,创建一个简单的 DAO 类来使用数据源:
java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
@Repository
public class UserDao {
private final JdbcTemplate jdbcTemplate;
@Autowired
public UserDao(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public void createUser(String name, String email) {
String sql = "INSERT INTO users (name, email) VALUES (?, ?)";
jdbcTemplate.update(sql, name, email);
}
}
最后,创建一个 Spring Boot 应用类来测试数据源配置:
java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootExample implements CommandLineRunner {
@Autowired
private UserDao userDao;
public static void main(String[] args) {
SpringApplication.run(SpringBootExample.class, args);
}
@Override
public void run(String... args) throws Exception {
userDao.createUser("John Doe", "john.doe@example.com");
System.out.println("User created successfully!");
}
}
3.2 代码解释
-
配置数据源:
yamlspring: datasource: url: jdbc:mysql://localhost:3306/mydb username: root password: secret driver-class-name: com.mysql.cj.jdbc.Driver
在
application.yaml
文件中,我们配置了数据库的 URL、用户名、密码和驱动类名。Spring Boot 会自动读取这些配置并创建DataSource
。 -
创建 DAO 类:
java@Repository public class UserDao { private final JdbcTemplate jdbcTemplate; @Autowired public UserDao(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } public void createUser(String name, String email) { String sql = "INSERT INTO users (name, email) VALUES (?, ?)"; jdbcTemplate.update(sql, name, email); } }
UserDao
类与 Spring MVC 示例中的相同,使用@Repository
注解标记为 Spring 的 DAO 组件,并通过构造函数注入JdbcTemplate
。 -
创建 Spring Boot 应用类:
java@SpringBootApplication public class SpringBootExample implements CommandLineRunner { @Autowired private UserDao userDao; public static void main(String[] args) { SpringApplication.run(SpringBootExample.class, args); } @Override public void run(String... args) throws Exception { userDao.createUser("John Doe", "john.doe@example.com"); System.out.println("User created successfully!"); } }
在
SpringBootExample
类中,我们使用@SpringBootApplication
注解来启用 Spring Boot 的自动配置。通过实现CommandLineRunner
接口,我们可以在应用启动后执行一些初始化操作,例如调用UserDao
的方法来创建用户。
4. 总结
通过以上三个部分的讲解,我们可以看到 Spring Boot 的自动配置机制是如何简化数据源配置的:
- 不使用任何框架:需要手动加载驱动、创建连接、执行 SQL 操作并关闭连接。
- 使用 Spring MVC:需要手动配置数据源 Bean,并通过依赖注入使用数据源。
- 使用 Spring Boot :只需在配置文件中配置数据库信息,Spring Boot 会自动创建
DataSource
和JdbcTemplate
,大大简化了配置过程。
整个架构的演变遵循着单一职责原则,将配置何代码分割开,提高内聚减少耦合,隐藏和业务无关的底层实现。这种思想我们可以在自己的编码工作中借鉴。