抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

SpringBoot整合JdbcTemplate

整合 JdbcTemplate

在 Java 领域,数据持久化有几个常见的方案,有 Spring 自带的 JdbcTemplate 、有 MyBatis,还有 JPA,在这些方案中,最简单的就是 Spring 自带的 JdbcTemplate 了,这个东西虽然没有 MyBatis 那么方便,但是比起最开始的 Jdbc 已经强了很多了,它没有 MyBatis 功能那么强大,当然也意味着它的使用比较简单,事实上,JdbcTemplate 算是最简单的数据持久化方案了,本文就和大伙来说说这个东西的使用。

导入坐标

在pom文件中加入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.22</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.19</version>
</dependency>

数据源配置

基于上面的但数据源或者多数据源配都可以

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
@RunWith(value = SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {DemoApplication.class})
public class DemoTest {
@Autowired
private JdbcTemplate jdbcTemplate;


@Test
public void test() throws SQLException {
query();
insert();
update();
delete();
}

//查询
public void query() {
jdbcTemplate.query("SELECT * FROM test", new RowMapper() {
@Override
public Object mapRow(ResultSet resultSet, int i) throws SQLException {
String name = resultSet.getString("name");
System.out.println(name);
return name;
}
});
}
//插入
public void insert() {
jdbcTemplate.update("INSERT INTO test (NAME) VALUES (?)", "插入操作");
}
// 更新
public void update() {
jdbcTemplate.update("update test set name =? where id = ?", 1, "xxxx");

}
//删除
public void delete() {
jdbcTemplate.update("delete from test where id = ?", 1);
}
}

原理分析

那么在 SpringBoot 中,配置完数据库基本信息之后,就有了一个 JdbcTemplate 了,这个东西是从哪里来的呢?源码在 org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration 类中,该类源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
@Configuration
@ConditionalOnClass({ DataSource.class, JdbcTemplate.class })
@ConditionalOnSingleCandidate(DataSource.class)
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
@EnableConfigurationProperties(JdbcProperties.class)
public class JdbcTemplateAutoConfiguration {
@Configuration
static class JdbcTemplateConfiguration {
private final DataSource dataSource;
private final JdbcProperties properties;
JdbcTemplateConfiguration(DataSource dataSource, JdbcProperties properties) {
this.dataSource = dataSource;
this.properties = properties;
}
@Bean
@Primary
@ConditionalOnMissingBean(JdbcOperations.class)
public JdbcTemplate jdbcTemplate() {
JdbcTemplate jdbcTemplate = new JdbcTemplate(this.dataSource);
JdbcProperties.Template template = this.properties.getTemplate();
jdbcTemplate.setFetchSize(template.getFetchSize());
jdbcTemplate.setMaxRows(template.getMaxRows());
if (template.getQueryTimeout() != null) {
jdbcTemplate
.setQueryTimeout((int) template.getQueryTimeout().getSeconds());
}
return jdbcTemplate;
}
}
@Configuration
@Import(JdbcTemplateConfiguration.class)
static class NamedParameterJdbcTemplateConfiguration {
@Bean
@Primary
@ConditionalOnSingleCandidate(JdbcTemplate.class)
@ConditionalOnMissingBean(NamedParameterJdbcOperations.class)
public NamedParameterJdbcTemplate namedParameterJdbcTemplate(
JdbcTemplate jdbcTemplate) {
return new NamedParameterJdbcTemplate(jdbcTemplate);
}
}
}

​ 从这个类中,大致可以看出,当前类路径下存在 DataSource 和 JdbcTemplate 时,该类就会被自动配置,jdbcTemplate 方法则表示,如果开发者没有自己提供一个 JdbcOperations 的实例的话,系统就自动配置一个 JdbcTemplate Bean(JdbcTemplate 是 JdbcOperations 接口的一个实现)。

整合多数据源

创建 JdbcTemplateConfig 类,用来提供两个不同的 JdbcTemplate 实例,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
@Configuration
public class JdbcTemplateConfig {

@Bean(name = "primaryJdbcTemplate")
JdbcTemplate jdbcTemplateOne(@Qualifier("primaryDatasource") DataSource primaryDatasource) {
return new JdbcTemplate(primaryDatasource);
}

@Bean(name = "secondJdbcTemplate")
JdbcTemplate jdbcTemplateTwo(@Qualifier("secondDatasource") DataSource secondDatasource) {
return new JdbcTemplate(secondDatasource);
}
}

每一个 JdbcTemplate 的创建都需要一个 DataSource,由于 Spring 容器中现在存在两个 DataSource,默认使用类型查找,会报错,因此加上 @Qualifier 注解,表示按照名称查找。这里创建了两个 JdbcTemplate 实例,分别对应了两个 DataSource。

接下来直接去使用这个 JdbcTemplate 就可以了。

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@RunWith(value = SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {DemoApplication.class})
public class DemoTest {
@Resource(name = "primaryJdbcTemplate")
private JdbcTemplate primaryJdbcTemplate;

@Resource(name = "secondJdbcTemplate")
private JdbcTemplate secondJdbcTemplate;

@Test
public void test() throws SQLException {
query(primaryJdbcTemplate);
query(secondJdbcTemplate);
}

public void query(JdbcTemplate jdbcTemplate) {
jdbcTemplate.query("SELECT * FROM test", new RowMapper() {
@Override
public Object mapRow(ResultSet resultSet, int i) throws SQLException {
String name = resultSet.getString("name");
System.out.println(name);
return name;
}
});
}
}

和 DataSource 一样,Spring 容器中的 JdbcTemplate 也是有两个,因此不能通过 byType 的方式注入进来,这里给大伙提供了两种注入思路,一种是使用 @Resource 注解,直接通过 byName 的方式注入进来,另外一种就是 @Autowired 注解加上 @Qualifier 注解,两者联合起来,实际上也是 byName。将 JdbcTemplate 注入进来之后,jdbcTemplateOne 和 jdbcTemplateTwo 此时就代表操作不同的数据源,使用不同的 JdbcTemplate 操作不同的数据源,实现了多数据源配置。

评论