Springboot-HikariCP 实现动态数据源切换

作者丨网络抖动 原文地址https://www.jianshu.com/p/05a8a1a2b50cgitHub
项目地址:https://github.com/shizhenshuang123/hikaricp-demo
开发环境:

  • jdk:JDK1.8+
  • gradle:Gradle4.6+
  • Spring:2.1.3.RELEASE+
image
image
导入依赖
  1. compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.1.3.RELEASE'

  2. compile group: 'org.springframework.boot', name: 'spring-boot-starter-jdbc', version: '2.1.3.RELEASE'

  3. compileOnly group: 'org.projectlombok', name: 'lombok', version: '1.18.6'

  4. compile group: 'mysql', name: 'mysql-connector-java', version: '8.0.15'

  5. compile group: 'org.mybatis.generator', name: 'mybatis-generator-core', version: '1.3.5'

  6. compile group: 'tk.mybatis', name: 'mapper', version: '4.0.2'

  7. compile group: 'org.mybatis.spring.boot', name: 'mybatis-spring-boot-starter', version: '2.0.0'

image
项目结构
配置文件配置(application.yaml)默认数据源信息
  1. spring:
  2. datasource:
  3. url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=CONVERT_TO_NULL&serverTimezone=Asia/Shanghai&allowMultiQueries=true
  4. username: root
  5. password: admin
  6. sql-script-encoding: UTF-8
读取配置信息 DataSourceConfig.java,创建默认的数据源
  1. package utry.hikaricp.config;

  2. import com.zaxxer.hikari.HikariDataSource;

  3. import org.springframework.beans.factory.annotation.Value;

  4. import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;

  5. import org.springframework.context.annotation.Bean;

  6. import org.springframework.context.annotation.Configuration;

  7. import org.springframework.transaction.annotation.EnableTransactionManagement;

  8. import utry.hikaricp.DataSourceProvider;

  9. import utry.hikaricp.info.DataSourceInfo;

  10. import utry.hikaricp.source.MyHikariDataSource;

  11. @Configuration

  12. @EnableTransactionManagement

  13. publicclassDataSourceConfig{

  14. @Value("${spring.datasource.url}")

  15. privateString url;

  16. @Value("${spring.datasource.username}")

  17. privateString userName;

  18. @Value("${spring.datasource.password}")

  19. privateString password;

  20. @Bean

  21. @ConditionalOnMissingBean(MyHikariDataSource.class)

  22. publicMyHikariDataSource dataSource() {

  23. DataSourceInfo info = newDataSourceInfo();

  24. info.setUrl(url);

  25. info.setUsername(userName);

  26. info.setPassword(password);

  27. HikariDataSource dataSource = DataSourceProvider.create(info);

  28. MyHikariDataSource hikariCPDataSource = newMyHikariDataSource();

  29. hikariCPDataSource.updateDataSourceMap("1", dataSource);

  30. return hikariCPDataSource;

  31. }

  32. }

通过 DataSourceProvider 创建 HikariDataSource
  1. package utry.hikaricp;

  2. import com.zaxxer.hikari.HikariConfig;

  3. import com.zaxxer.hikari.HikariDataSource;

  4. import utry.hikaricp.info.DataSourceInfo;

  5. publicclassDataSourceProvider{

  6. publicstaticHikariDataSource create(DataSourceInfo sourceInfo) {

  7. HikariConfig hikariConfig = newHikariConfig();

  8. hikariConfig.setUsername(sourceInfo.getUsername());

  9. hikariConfig.setPassword(sourceInfo.getPassword());

  10. hikariConfig.setJdbcUrl(sourceInfo.getUrl());

  11. hikariConfig.setDriverClassName("com.mysql.jdbc.Driver");

  12. returnnewHikariDataSource(hikariConfig);

  13. }

  14. }

最核心的数据源的类 MyHikariDataSource.java
  1. package utry.hikaricp.source;

  2. import com.zaxxer.hikari.HikariDataSource;

  3. import org.springframework.jdbc.datasource.AbstractDataSource;

  4. import javax.sql.DataSource;

  5. import java.io.Closeable;

  6. import java.io.IOException;

  7. import java.sql.Connection;

  8. import java.sql.SQLException;

  9. import java.util.HashMap;

  10. import java.util.Map;

  11. publicclassMyHikariDataSourceextendsAbstractDataSource{

  12. privatestaticMap<String, HikariDataSource> dataSourceMap = newHashMap<>(1);

  13. @Override

  14. publicConnection getConnection() throwsSQLException{

  15. return dataSourceMap.get("1").getConnection();

  16. }

  17. @Override

  18. publicConnection getConnection(String username, String password) throwsSQLException{

  19. return dataSourceMap.get("1").getConnection(username, password);

  20. }

  21. privatevoid destroy(){

  22. DataSource dataSource = dataSourceMap.get("1");

  23. Closeable closeable = (Closeable) dataSource;

  24. if(closeable != null) {

  25. try{

  26. closeable.close();

  27. } catch(IOException e) {

  28. e.printStackTrace();

  29. }

  30. }

  31. }

  32. publicvoid updateDataSourceMap(String key, HikariDataSource value) {

  33. destroy();

  34. dataSourceMap.put(key, value);

  35. }

  36. }

只要将上面这个类中的 DataSourceMap 集合中的 HikariDataSource 修改就能实现数据源的切换了,调用 updateDataSourceMap() 方法修改即可(修改之前,先关闭之前的数据源,这里写死的 map 中 key=1,读者可以实现动态设置)


实体类 UserInfo.java
  1. package utry.hikaricp.model;

  2. publicclassUserInfo{

  3. privateInteger id;

  4. privateString remarks;

  5. publicUserInfo() {

  6. }

  7. publicUserInfo(Integer id, String remarks) {

  8. this.id = id;

  9. this.remarks = remarks;

  10. }

  11. publicInteger getId() {

  12. return id;

  13. }

  14. publicvoid setId(Integer id) {

  15. this.id = id;

  16. }

  17. publicString getRemarks() {

  18. return remarks;

  19. }

  20. publicvoid setRemarks(String remarks) {

  21. this.remarks = remarks;

  22. }

  23. }

HikariCpController.java 两个接口:
  1. 更新数据源

  2. 查询用户信息

  3. package utry.hikaricp.controller;

  4. import org.springframework.beans.factory.annotation.Autowired;

  5. import org.springframework.web.bind.annotation.RequestMapping;

  6. import org.springframework.web.bind.annotation.RestController;

  7. import utry.hikaricp.factory.HikariCPDataSourceFactory;

  8. import utry.hikaricp.mapper.UserInfoMapper;

  9. import utry.hikaricp.model.UserInfo;

  10. @RestController

  11. publicclassHikariCpController{

  12. @Autowired

  13. privateUserInfoMapper mapper;

  14. @Autowired

  15. privateHikariCPDataSourceFactory factory;

  16. @RequestMapping("update")

  17. publicvoid info(String username, String password, String url) {

  18. factory.reload(username, password, url);

  19. }

  20. @RequestMapping("get")

  21. publicUserInfoget() {

  22. try{

  23. UserInfo userInfo = mapper.selectByPrimaryKey(1);

  24. return userInfo;

  25. } catch(Exception e) {

  26. e.printStackTrace();

  27. }

  28. returnnull;

  29. }

  30. }

</pre>

启动项目
image
image
image
image
image
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值