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 操作不同的数据源,实现了多数据源配置。