小码农的代码(三)----------SpringJDBC多数据源应用

2024-09-04 12:38

本文主要是介绍小码农的代码(三)----------SpringJDBC多数据源应用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前面项目中基础的SpringJdbc的配置说明已经简单总结,接下去就是项目中使用到多数据源这个问题了。 
对于多数据源的实现,我的想法是首先配置多个数据源,然后在数据操作时通过切换数据源的方式来达到目的,那么如何在保持jdbctmplate只有一个的时候进行数据源切换呢,我考虑到可以起一个线程来实现在操作中的自由切换。 
首先配置3个数据源,为方便测试就直接在本机新建了三个mysql数据库(实际过程中是使用mysql与多个sql server)来写测试用例
Java代码   收藏代码
  1. <bean id="defaultDateSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"  
  2.         destroy-method="close">  
  3.         <property name="driverClass" value="${jdbc.driverClass}" />  
  4.         <property name="jdbcUrl" value="${jdbc.jdbcUrl}" />  
  5.         <property name="user" value="${jdbc.user}" />  
  6.         <property name="password" value="${jdbc.password}" />  
  7.     </bean>  
Java代码   收藏代码
  1. <bean id="dataSource01" class="com.mchange.v2.c3p0.ComboPooledDataSource"  
  2.         destroy-method="close">  
  3.         <property name="driverClass" value="${jdbc.driverClass01}" />  
  4.         <property name="jdbcUrl" value="${jdbc.jdbcUrl01}" />  
  5.         <property name="user" value="${jdbc.user01}" />  
  6.         <property name="password" value="${jdbc.password01}" />  
  7.     </bean>  
Java代码   收藏代码
  1. <bean id="dataSource02" class="com.mchange.v2.c3p0.ComboPooledDataSource"  
  2.         destroy-method="close">  
  3.         <property name="driverClass" value="${jdbc.driverClass02}" />  
  4.         <property name="jdbcUrl" value="${jdbc.jdbcUrl02}" />  
  5.         <property name="user" value="${jdbc.user02}" />  
  6.         <property name="password" value="${jdbc.password02}" />  
  7.     </bean>  
习惯使用c3p0数据库连接池,下次尝试试用下阿里DruidDataSource,据说功能更加强大,但是一直没有使用过-,-跑题了 新建三个数据库还是只有一个表user(id,name,age;id逐渐自增)。 
然后新建一个单例的线程ThreadLocal(这是一个很好用的东西,下次专门写个测试用例总结下,做项目总是能够不断的引出新的东西,这点真的很好),能够set/get/remove数据源
Java代码   收藏代码
  1. public class DatabaseContextHolder {  
  2.     private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();  
  3.   
  4.     public static void setDateBaseType(String database) {  
  5.         Assert.notNull(database, "DatabaseType cannot be null");  
  6.         contextHolder.set(database);  
  7.     }  
  8.   
  9.     public static String getDateBaseType() {  
  10.         return contextHolder.get();  
  11.     }  
  12.   
  13.     public static void clearDatabaseType() {  
  14.         contextHolder.remove();  
  15.     }  
  16. }  

接下来是Spring支持多数据源切换的核心类AbstractRoutingDataSource,新建一个继承这个抽象类的子类DynamicDataSource,并实现determineCurrentLookupKey方法(抽象类与接口的相似性
Java代码   收藏代码
  1. public class DynamicDataSource extends AbstractRoutingDataSource {  
  2.   
  3.     @Override  
  4.     protected Object determineCurrentLookupKey() {  
  5.         return DatabaseContextHolder.getDateBaseType();  
  6.     }  
  7. }  

继续回到spring的配置文件,通过DynamicDataSource管理多数据源,并设置默认的数据源
Java代码   收藏代码
  1. <bean id="dynamicDataSource" class="com.zh.demo.base.tool.DynamicDataSource">  
  2.         <property name="targetDataSources">  
  3.             <map key-type="java.lang.String">  
  4.                 <entry value-ref="defaultDateSource" key="defaultDateSource"></entry>  
  5.                 <entry value-ref="dataSource01" key="dataSource01"></entry>  
  6.                 <entry value-ref="dataSource02" key="dataSource02"></entry>  
  7.             </map>  
  8.         </property>  
  9.         <property name="defaultTargetDataSource" ref="defaultDateSource">  
  10.         </property>  
  11.     </bean>  
当然jdbctemplate中指向的数据源也需要切换成它
Java代码   收藏代码
  1. <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">  
  2.         <property name="dataSource" ref="dynamicDataSource" />  
最后新建一个DataBaseType类与配置中的数据源名称相关联
Java代码   收藏代码
  1. public class DataBaseType {  
  2.     public static final String DATABASE_DEFAULT = "defaultDateSource";  
  3.     public static final String DATABASE_01 = "dataSource01";  
  4.     public static final String DATABASE_02 = "dataSource02";  
  5. }  
这样就可以写测试用例了。 
简单的新增语句在测试类中进行数据库切换
Java代码   收藏代码
  1. public void test(){  
  2.         userService.saveUser(("insert into user (name,age)values('张三',13)");  
  3.         DatabaseContextHolder.clearDatabaseType();  
  4.         DatabaseContextHolder.setDateBaseType(DataBaseType.DATABASE_01);  
  5.         userService.saveUser("insert into user (name,age)values('张三',13)");  
  6.         DatabaseContextHolder.clearDatabaseType();  
  7.         DatabaseContextHolder.setDateBaseType(DataBaseType.DATABASE_02);  
  8.         userService.saveUser("insert into user (name,age)values('张三',13)");  
  9.     }  
结果是三个数据库中都插入了数据,多数据源配置成功。 
注意点与总结: 
一、实际项目中发现一个问题,就是在同一个事务中不能够进行数据库切换,该问题暂时未解决,有方法的朋友可以的话烦请指导下。 
二、在使用过程中扩展想到能否通过请求来动态的切换数据源,目前考虑到还是需要在请求中带参数来让后台识别进行数据库切换,不知道有没有更好的方法。 
以下内容如存在错误之处烦请斧正以达到共同进步的效果,多谢。
  • SpringJDBC_多数据源_.rar (33.4 KB)
  • 下载次数: 6

这篇关于小码农的代码(三)----------SpringJDBC多数据源应用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1136047

相关文章

Java集合之Iterator迭代器实现代码解析

《Java集合之Iterator迭代器实现代码解析》迭代器Iterator是Java集合框架中的一个核心接口,位于java.util包下,它定义了一种标准的元素访问机制,为各种集合类型提供了一种统一的... 目录一、什么是Iterator二、Iterator的核心方法三、基本使用示例四、Iterator的工

Java 线程池+分布式实现代码

《Java线程池+分布式实现代码》在Java开发中,池通过预先创建并管理一定数量的资源,避免频繁创建和销毁资源带来的性能开销,从而提高系统效率,:本文主要介绍Java线程池+分布式实现代码,需要... 目录1. 线程池1.1 自定义线程池实现1.1.1 线程池核心1.1.2 代码示例1.2 总结流程2. J

利用Python操作Word文档页码的实际应用

《利用Python操作Word文档页码的实际应用》在撰写长篇文档时,经常需要将文档分成多个节,每个节都需要单独的页码,下面:本文主要介绍利用Python操作Word文档页码的相关资料,文中通过代码... 目录需求:文档详情:要求:该程序的功能是:总结需求:一次性处理24个文档的页码。文档详情:1、每个

JS纯前端实现浏览器语音播报、朗读功能的完整代码

《JS纯前端实现浏览器语音播报、朗读功能的完整代码》在现代互联网的发展中,语音技术正逐渐成为改变用户体验的重要一环,下面:本文主要介绍JS纯前端实现浏览器语音播报、朗读功能的相关资料,文中通过代码... 目录一、朗读单条文本:① 语音自选参数,按钮控制语音:② 效果图:二、朗读多条文本:① 语音有默认值:②

Vue实现路由守卫的示例代码

《Vue实现路由守卫的示例代码》Vue路由守卫是控制页面导航的钩子函数,主要用于鉴权、数据预加载等场景,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着... 目录一、概念二、类型三、实战一、概念路由守卫(Navigation Guards)本质上就是 在路

uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)

《uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)》在uni-app开发中,文件上传和图片处理是很常见的需求,但也经常会遇到各种问题,下面:本文主要介绍uni-app小程序项目中实... 目录方式一:使用<canvas>实现图片压缩(推荐,兼容性好)示例代码(小程序平台):方式二:使用uni

JAVA实现Token自动续期机制的示例代码

《JAVA实现Token自动续期机制的示例代码》本文主要介绍了JAVA实现Token自动续期机制的示例代码,通过动态调整会话生命周期平衡安全性与用户体验,解决固定有效期Token带来的风险与不便,感兴... 目录1. 固定有效期Token的内在局限性2. 自动续期机制:兼顾安全与体验的解决方案3. 总结PS

C#中通过Response.Headers设置自定义参数的代码示例

《C#中通过Response.Headers设置自定义参数的代码示例》:本文主要介绍C#中通过Response.Headers设置自定义响应头的方法,涵盖基础添加、安全校验、生产实践及调试技巧,强... 目录一、基础设置方法1. 直接添加自定义头2. 批量设置模式二、高级配置技巧1. 安全校验机制2. 类型

Python屏幕抓取和录制的详细代码示例

《Python屏幕抓取和录制的详细代码示例》随着现代计算机性能的提高和网络速度的加快,越来越多的用户需要对他们的屏幕进行录制,:本文主要介绍Python屏幕抓取和录制的相关资料,需要的朋友可以参考... 目录一、常用 python 屏幕抓取库二、pyautogui 截屏示例三、mss 高性能截图四、Pill

使用MapStruct实现Java对象映射的示例代码

《使用MapStruct实现Java对象映射的示例代码》本文主要介绍了使用MapStruct实现Java对象映射的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,... 目录一、什么是 MapStruct?二、实战演练:三步集成 MapStruct第一步:添加 Mave