Spring Boot中手动实例化 `JdbcTemplate` 并指定 数据源

一、核心前提:确保 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

若项目存在多个数据源(如 sourceDataSourcetargetDataSource),可分别实例化对应的 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"));
        }
    }
}

四、注意事项

  1. 避免重复实例化 :手动 new JdbcTemplate 会导致每次创建新实例,建议将其注册为Spring Bean(单例模式),全局复用;
  2. 数据源必须有效 :确保 sourceDataSource 配置正确(URL、用户名、密码无误),驱动已引入(如MySQL驱动需在pom.xml中添加依赖);
  3. 国产数据库适配 :若使用达梦/人大金仓等国产数据库,需替换驱动类(如达梦:dm.jdbc.driver.DmDriver)和URL(如 jdbc:dm://localhost:5236/source_db);
  4. 连接池配置:优先使用Spring Boot内置的HikariCP连接池,合理配置最大连接数、最小空闲数,避免连接泄露;
  5. 异常处理 :使用 JdbcTemplate 时需捕获 DataAccessException 异常,处理数据库连接失败、SQL语法错误等问题。

总结

  1. 核心步骤:先配置并注入 sourceDataSource,再通过 new JdbcTemplate(sourceDataSource) 实例化;
  2. 推荐方式:将 JdbcTemplate 注册为Spring Bean(@Bean),通过 @Autowired+@Qualifier 注入使用,支持多数据源隔离;
  3. 单数据源简化:Spring Boot自动配置 JdbcTemplate,直接注入即可,无需手动实例化;
  4. 关键保障:确保数据源配置有效、驱动已引入,避免重复实例化造成资源浪费。
相关推荐
liuyao_xianhui2 小时前
优选算法_topk问题_快速排序算法_堆_C++
java·开发语言·数据结构·c++·算法·链表·排序算法
liuyao_xianhui2 小时前
优选算法_堆_最后一块石头的重量_C++
java·开发语言·c++·算法·链表
好家伙VCC2 小时前
# 发散创新:基于状态通道的以太坊智能合约高效交互实践在区块链应用开发中,**交易
java·python·区块链·智能合约
羊小猪~~2 小时前
算法/力扣--栈与队列经典题目
开发语言·c++·后端·考研·算法·leetcode·职场和发展
Noushiki2 小时前
数据一致性保障方案 -java后端
java·开发语言
Meepo_haha2 小时前
Maven Spring框架依赖包
java·spring·maven
studyForMokey2 小时前
【Android面试】ViewModel & LiveData & EventBus专题
android·java·面试
迷藏4942 小时前
# 发散创新:用Rust构建高性能分布式账本节点——从零实现共识算法与链上数据存储
java·python·rust·共识算法·分布式账本
Flittly2 小时前
【SpringAIAlibaba新手村系列】(5)Prompt 提示词基础与多种消息类型
java·笔记·spring·ai·springboot