一、核心前提:确保 sourceDataSource 已被Spring容器管理
手动实例化 JdbcTemplate 的前提是 sourceDataSource 必须是一个有效的 DataSource 实例(通常需纳入Spring容器管理,保证数据源配置生效、连接池正常工作)。
1. 先配置 sourceDataSource 数据源(application.yml/application.properties)
以 application.yml 为例,配置数据源信息(以MySQL为例,适配国产数据库可替换驱动与URL):
yaml
# 数据源配置(sourceDataSource)
spring:
datasource:
source:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/source_db?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
username: root
password: 123456
# 连接池配置(默认HikariCP,Spring Boot内置)
hikari:
maximum-pool-size: 10
minimum-idle: 2
connection-timeout: 30000
2. 配置 sourceDataSource 实例(注入Spring容器)
通过配置类将 sourceDataSource 注册为Spring Bean,供后续实例化 JdbcTemplate 使用:
java
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
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 DataSourceConfig {
/**
* 配置sourceDataSource,纳入Spring容器管理
* @return 数据源实例
*/
@Bean(name = "sourceDataSource")
@ConfigurationProperties(prefix = "spring.datasource.source") // 绑定yml中的配置前缀
@Primary // 若有多个数据源,指定默认数据源(可选)
public DataSource sourceDataSource() {
// Spring Boot默认使用HikariCP连接池,直接构建即可
return new HikariDataSource();
}
}
二、三种实例化 JdbcTemplate 的方式
方式1:手动直接实例化(非推荐,适用于临时测试/非容器管理场景)
直接通过 new 关键字创建 JdbcTemplate,传入 sourceDataSource 实例:
java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
@Component
public class TestJdbcComponent {
// 从Spring容器中注入sourceDataSource
@Autowired
@Qualifier("sourceDataSource") // 若数据源Bean有名称,需指定Qualifier
private DataSource sourceDataSource;
// 手动实例化JdbcTemplate
public JdbcTemplate getSourceJdbcTemplate() {
// 直接传入sourceDataSource创建JdbcTemplate实例
JdbcTemplate jdbcTemplate = new JdbcTemplate(sourceDataSource);
// 可选:配置JdbcTemplate属性(如查询超时时间)
jdbcTemplate.setQueryTimeout(30); // 查询超时30秒
return jdbcTemplate;
}
// 测试使用
public void testQuery() {
JdbcTemplate jdbcTemplate = getSourceJdbcTemplate();
String sql = "SELECT COUNT(*) FROM user";
Integer count = jdbcTemplate.queryForObject(sql, Integer.class);
System.out.println("用户总数:" + count);
}
}
方式2:将 JdbcTemplate 注册为Spring Bean(推荐,全局复用)
将实例化后的 JdbcTemplate 注入Spring容器,供整个项目复用(无需重复创建):
java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
@Configuration
public class JdbcTemplateConfig {
/**
* 实例化source对应的JdbcTemplate,注册为Spring Bean
* @param sourceDataSource 自动注入容器中的sourceDataSource
* @return JdbcTemplate实例
*/
@Bean(name = "sourceJdbcTemplate")
public JdbcTemplate sourceJdbcTemplate(@Qualifier("sourceDataSource") DataSource sourceDataSource) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(sourceDataSource);
// 可选配置
jdbcTemplate.setQueryTimeout(30);
jdbcTemplate.setIgnoreWarnings(true);
return jdbcTemplate;
}
}
使用时直接注入 JdbcTemplate 即可:
java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.jdbc.core.JdbcTemplate;
@Service
public class UserService {
// 注入已实例化的sourceJdbcTemplate
@Autowired
@Qualifier("sourceJdbcTemplate")
private JdbcTemplate sourceJdbcTemplate;
public Integer getUserCount() {
String sql = "SELECT COUNT(*) FROM user";
return sourceJdbcTemplate.queryForObject(sql, Integer.class);
}
}
方式3:Spring Boot自动配置(单数据源场景,最简)
若项目只有 sourceDataSource 一个数据源,Spring Boot会自动实例化 JdbcTemplate ,无需手动 new,直接注入即可使用:
java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.jdbc.core.JdbcTemplate;
@Service
public class OrderService {
// Spring Boot自动配置的JdbcTemplate,默认使用主数据源(sourceDataSource)
@Autowired
private JdbcTemplate jdbcTemplate;
public String getOrderName(Long orderId) {
String sql = "SELECT order_name FROM `order` WHERE id = ?";
return jdbcTemplate.queryForObject(sql, new Object[]{orderId}, String.class);
}
}
三、多数据源场景:实例化多个 JdbcTemplate
若项目存在多个数据源(如 sourceDataSource 和 targetDataSource),可分别实例化对应的 JdbcTemplate:
java
@Configuration
public class MultiJdbcTemplateConfig {
// 数据源1:sourceDataSource
@Bean(name = "sourceDataSource")
@ConfigurationProperties(prefix = "spring.datasource.source")
public DataSource sourceDataSource() {
return new HikariDataSource();
}
// 数据源2:targetDataSource
@Bean(name = "targetDataSource")
@ConfigurationProperties(prefix = "spring.datasource.target")
public DataSource targetDataSource() {
return new HikariDataSource();
}
// JdbcTemplate1:对应sourceDataSource
@Bean(name = "sourceJdbcTemplate")
public JdbcTemplate sourceJdbcTemplate(@Qualifier("sourceDataSource") DataSource sourceDataSource) {
return new JdbcTemplate(sourceDataSource);
}
// JdbcTemplate2:对应targetDataSource
@Bean(name = "targetJdbcTemplate")
public JdbcTemplate targetJdbcTemplate(@Qualifier("targetDataSource") DataSource targetDataSource) {
return new JdbcTemplate(targetDataSource);
}
}
使用时通过 @Qualifier 指定对应的 JdbcTemplate:
java
@Service
public class DataSyncService {
@Autowired
@Qualifier("sourceJdbcTemplate")
private JdbcTemplate sourceJdbcTemplate;
@Autowired
@Qualifier("targetJdbcTemplate")
private JdbcTemplate targetJdbcTemplate;
// 从源数据源查询,写入目标数据源
public void syncUser() {
// 源数据源查询
String querySql = "SELECT id, username FROM user";
List<Map<String, Object>> userList = sourceJdbcTemplate.queryForList(querySql);
// 目标数据源写入
String insertSql = "INSERT INTO user (id, username) VALUES (?, ?)";
for (Map<String, Object> user : userList) {
targetJdbcTemplate.update(insertSql, user.get("id"), user.get("username"));
}
}
}
四、注意事项
- 避免重复实例化 :手动
new JdbcTemplate会导致每次创建新实例,建议将其注册为Spring Bean(单例模式),全局复用; - 数据源必须有效 :确保
sourceDataSource配置正确(URL、用户名、密码无误),驱动已引入(如MySQL驱动需在pom.xml中添加依赖); - 国产数据库适配 :若使用达梦/人大金仓等国产数据库,需替换驱动类(如达梦:
dm.jdbc.driver.DmDriver)和URL(如jdbc:dm://localhost:5236/source_db); - 连接池配置:优先使用Spring Boot内置的HikariCP连接池,合理配置最大连接数、最小空闲数,避免连接泄露;
- 异常处理 :使用
JdbcTemplate时需捕获DataAccessException异常,处理数据库连接失败、SQL语法错误等问题。
总结
- 核心步骤:先配置并注入
sourceDataSource,再通过new JdbcTemplate(sourceDataSource)实例化; - 推荐方式:将
JdbcTemplate注册为Spring Bean(@Bean),通过@Autowired+@Qualifier注入使用,支持多数据源隔离; - 单数据源简化:Spring Boot自动配置
JdbcTemplate,直接注入即可,无需手动实例化; - 关键保障:确保数据源配置有效、驱动已引入,避免重复实例化造成资源浪费。