1、 概述
不夸张地说,系统的运行过程就是处理数据的过程,数据的结构多种多样:结构化数据、半结构化数据以及非结构化数。
结构化数据作为数据中的一个庞大群体,在各市各样的系统中充当着重要的角色,本篇就研究下Spring Boot如何与关系型数据库进行集成工作的。相关源码可以从这里下载。
2、配置单个数据源
在配置文件中通过一些属性(spring.datasource.*)可以控制数据源的配置,比如:
spring:
datasource:
url: "jdbc:mysql://localhost/test"
username: "dbuser"
password: "dbpass"
当然配置数据源时也可以在配置文件中指定一些不同的前缀,以获取特定的数据源,比如:
spring.datasource.hikari.*,
spring.datasource.tomcat.*,
spring.datasource.dbcp2.*,
spring.datasource.oracleucp.*
如果使用的是Tomcat连接池,可以额外添加一些属性,如:
spring:
datasource:
tomcat:
max-wait: 10000
max-active: 50
test-on-borrow: true
max-wait: 10000,表示如果获取不到连接会等待10000ms;
max-active: 50, 限制最大连接数为50;
test-on-borrow:true,表示从池中借一个连接之前,对其进行验证。
支持的连接池
- 优先使用HikariCP,因其有较好的性能和并发性
- 其次使用Tomcat连接池
- 再次使用Commons-DBCP2
- 最后如果没有HikariCP、Tomcat及DBCP2,如果Oracle UCP可用,则会使用 Oracle UCP
当在pom中引入了spring-boot-starter-jdbc后,会级联引入HikariCP的依赖,所以默认支持的连接池就是HikariCP
切换数据源
如果要使用tomcat连接池,可以在pom中引入tomcat-jdbc依赖
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
<version>9.0.10</version>
</dependency>
此时若不将spring-boot-starter-jdbc依赖中的HikariCP进行排除(如下形式),虽然添加了tomcat-jdbc依赖,使用的依然是HikariCP数据源,有两种方式可以切换到tomcat-jdbc数据源。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<exclusions>
<exclusion>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</exclusion>
</exclusions>
</dependency>
方式一:
可以通过在application.properites中设定spring.datasource.type属性来指定使用哪种连接池,在yml中的写法如下:
spring:
datasource:
type: org.apache.tomcat.jdbc.pool.DataSource
方式二:
就是将spring-boot-starter-jdbc依赖中的HikariCP进行排除,如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<exclusions>
<exclusion>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</exclusion>
</exclusions>
</dependency>
若要使用DBCP2或Oracle UCP数据源,引入相应的依赖即可,具体版本视具体情况而定,内容如下:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.2.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.oracle.database.jdbc/ucp -->
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ucp</artifactId>
<version>18.3.0.0</version>
</dependency>
3、切换为第三数据源
下面以druid数据源为例,说明下如何引入第三方数据源,在pom文件中,引入如下所示的druid依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.12</version>
</dependency>
定义一个配置类DataSourceConfig,该类的关键作用在于会返回DruidDataSource类的对象,这里以@Bean的方式返回DruidDataSource类的对象,有多种不同的方法返回类的对象,主要区别在于读取数据库连接信息的方式不同,下面展示了两种,择其一使用即可:
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import javax.sql.DataSource;
@Configuration
public class DataSourceConfig {
@Autowired
private Environment environment;
//第一种方式
/*@Bean
public DataSource getDataSource() {
DruidDataSource druidDataSource = new DruidDataSource();
String dataSourceUrl = environment.getProperty(environment.getProperty("spring.datasource.url"));
String dataSourceUsername = environment.getProperty("spring.datasource.username");
String dataSourcePassword = environment.getProperty("spring.datasource.password");
druidDataSource.setUrl(dataSourceUrl);
druidDataSource.setUsername(dataSourceUsername);
druidDataSource.setPassword(dataSourcePassword);
return druidDataSource;
}*/
//第二种方式
@ConfigurationProperties("spring.datasource")
@Bean
public DataSource dataSource() {
DruidDataSource druidDataSource = new DruidDataSource();
return druidDataSource;
}
}
4、使用数据源
当有了DataSource后,就可将其注入到使用它的地方进行使用,比如可以创建Controller层,在里面对进行查询操作,主要思路就是从DataSource的对象中获取数据库连接,接着执行SQL查询,代码如下:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
@RestController
public class DataSourceController {
@Autowired
private DataSource dataSource;
@GetMapping("select")
public List<String> getUsers() {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
List<String> users = new ArrayList<>();
try {
connection = dataSource.getConnection();
preparedStatement = connection.prepareStatement("select name from c_user");
resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
String user = resultSet.getString(1);
users.add(user);
}
} catch (Exception e) {
e.printStackTrace();
}
return users;
}
}
上面虽然演示了如何从DataSource对象获取连接等操作,但是实际开发中基本不会采用这种方式对数据库进行操作,基本都会采用MyBatis、Hibernate、JPA或JdbcTemplate等操作数据库, 当创建了DataSource后,Spring Boot中的org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration类会自动配置JdbcTemplate bean,它的使用方式如下:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
@RestController
public class DataSourceController {
@Autowired
private DataSource dataSource;
@Autowired
JdbcTemplate jdbcTemplate;
@GetMapping("select2")
public List<String> getUsers2() {
String sql = "select name from c_user";
List<String> users = jdbcTemplate.queryForList(sql, String.class);
return users;
}
}
5、回顾
以上内容展示了,如何在SpringBoot2.5.4版本中使用默认支持的数据源(HikariCP、tomcat-jdbc、Commons-DBCP2、Oracle UCP),以及如何配置第三方数据源(以druid为例),接下来会展示如何配置多数据源的问题。