欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

SSM+Druid实现动态多数据源切换(已实践)

发布时间:2025/3/19 编程问答 56 豆豆
生活随笔 收集整理的这篇文章主要介绍了 SSM+Druid实现动态多数据源切换(已实践) 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

场景

两个数据库,完成增删改查时同时对两个数据库进行操作。


实现

1.在web.xml中配置spring的配置文件

<!-- 配置Spring配置文件的位置 --><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring.xml</param-value></context-param>

2.在spring.xml中引入属性文件

<!-- 引入属性文件 --><context:property-placeholder location="classpath:config.properties" /><context:property-placeholder location="classpath:databaseType.properties" />

3.打开config.properties

除了其他正常配置外,添加两个连接数据库的url。

添加如下:

driverClassName=com.mysql.jdbc.Driver validationQuery=SELECT 1sys_url=jdbc:mysql://数据库1?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true sys_username= sys_password=demo_url=jdbc:mysql://数据库2?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true demo_username= demo_password=

4.打开databaseType.properties

#sysDs 1 = sysDs #demoDS 2 = demoDs


5.再回到spring.xml

其他配置正常,这里省略。

导入其他spring配置文件

<!-- 导入其他spring配置文件 --><import resource="spring-database.xml" />

6.打开spring-database.xml

设置动态切换数据源

<!-- 动态切换数据源 --><bean id="dataSource" class="com.wongoing.datasource.DynamicDataSource"><property name="targetDataSources"><map key-type="java.lang.String"><entry key="sysDs" value-ref="sysDs" /><entry key="demoDs" value-ref="demoDs" /></map></property><!-- 默认数据源 --><property name="defaultTargetDataSource" ref="sysDs" /></bean>

紧接着配置两个数据源

 <!-- 系统库数据源 --><bean name="sysDs" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"><property name="driverClassName" value="${driverClassName}" /><property name="url" value="${sys_url}" /><property name="username" value="${sys_username}" /><property name="password" value="${sys_password}" /><!-- 初始化连接大小 --><property name="initialSize" value="0" /><!-- 最小空闲连接数 --><property name="minIdle" value="0" /><!-- 连接池最大活跃连接数量 --><property name="maxActive" value="50" /><!-- 获取连接最大等待时间 --><property name="maxWait" value="60000" /><!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 --><property name="timeBetweenEvictionRunsMillis" value="300000" /><!-- 配置一个连接在池中最小生存的时间,单位是毫秒 --><property name="minEvictableIdleTimeMillis" value="300000" /><!-- 测试连接,单位为毫秒 --><property name="validationQueryTimeout" value="300000" /><property name="validationQuery" value="${validationQuery}" /><property name="testWhileIdle" value="true" /><property name="testOnBorrow" value="false" /><property name="testOnReturn" value="false" />  <!-- 打开PSCache,并且指定每个连接上PSCache的大小 --><!-- 如果用Oracle,则把poolPreparedStatements配置为true,MySQL可以配置为false --><property name="poolPreparedStatements" value="true" /><property name="maxPoolPreparedStatementPerConnectionSize" value="50" /><!-- 打开removeAbandoned功能 --><property name="removeAbandoned" value="true" /><!-- 3600秒,也就是60分钟 --><property name="removeAbandonedTimeout" value="3600" /><!-- 关闭abanded连接时输出错误日志 --><property name="logAbandoned" value="true" /></bean><!-- 演示数据源 --><bean name="demoDs" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"><property name="driverClassName" value="${driverClassName}" /><property name="url" value="${demo_url}" /><property name="username" value="${demo_username}" /><property name="password" value="${demo_password}" /><!-- 初始化连接大小 --><property name="initialSize" value="0" /><!-- 最小空闲连接数 --><property name="minIdle" value="0" /><!-- 连接池最大活跃连接数量 --><property name="maxActive" value="50" /><!-- 获取连接最大等待时间 --><property name="maxWait" value="60000" /><!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 --><property name="timeBetweenEvictionRunsMillis" value="300000" /><!-- 配置一个连接在池中最小生存的时间,单位是毫秒 --><property name="minEvictableIdleTimeMillis" value="300000" /><!-- 测试连接,单位为毫秒 --><property name="validationQueryTimeout" value="300000" /><property name="validationQuery" value="${validationQuery}" /><property name="testWhileIdle" value="true" /><property name="testOnBorrow" value="false" /><property name="testOnReturn" value="false" />  <!-- 打开PSCache,并且指定每个连接上PSCache的大小 --><!-- 如果用Oracle,则把poolPreparedStatements配置为true,MySQL可以配置为false --><property name="poolPreparedStatements" value="true" /><property name="maxPoolPreparedStatementPerConnectionSize" value="50" /><!-- 打开removeAbandoned功能 --><property name="removeAbandoned" value="true" /><!-- 3600秒,也就是60分钟 --><property name="removeAbandonedTimeout" value="3600" /><!-- 关闭abanded连接时输出错误日志 --><property name="logAbandoned" value="true" /></bean>

然后配置事务管理

   

<!-- 开启事务注解驱动 --> <tx:annotation-driven /> <!-- (事务管理)transaction manager, use JtaTransactionManager for global tx --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> 

7.新建DataSourceHolder类

新建datasource包 ,包下新建DataSourceHolder.java

package com.badao.datasource;public class DataSourceHolder {//线程本地环境private static final ThreadLocal<String> dataSources = new ThreadLocal<String>();//设置数据源public static void setDataSource(String customerType) {dataSources.set(customerType);}//获取数据源public static String getDataSource() {return (String) dataSources.get();}//清除数据源public static void clearDataSource() {dataSources.remove();} }

8.业务实现

import com.badao.datasource.DataSourceHolder;@Description("信息保存")@ResponseBody@RequestMapping(value = "/doSave")public Map<String, Object> doSave(TbMessage entity, String op, String base64Str, String[] itemIdStr) {Map<String, Object> jsonResult = null;String msg = "";try {if (base64Str.length()!= 0) {String result = ImageUtil.getInstance().baseUploadImg(Constants.UPLOAD_IMG_MESSAGE, base64Str);entity.setThemeImageUrl((String) result);}String tabid = tabid(ModelAndViewConstants.MESSAGE_SYS_ID);Date now = new Date();ShiroUser currentUser = (ShiroUser) SecurityUtils.getSubject().getPrincipal();// 添加if (null == op || ModelAndViewConstants.OPERATION_VALUE_ADD.equals(op)) {entity.setStatus("0");entity.setRecordTime(now);entity.setUserId(currentUser.getUserId());this.service.insert(entity);DataSourceHolder.setDataSource("demoDs");//切换云端数据源this.service.insert(entity);DataSourceHolder.setDataSource("sysDs");//切换本地数据源} else {// 编辑entity.setModifyDate(now);this.service.updateByPrimaryKey(entity);DataSourceHolder.setDataSource("demoDs");//切换云端数据源this.service.updateByPrimaryKey(entity);DataSourceHolder.setDataSource("sysDs");//切换本地数据源}Integer statusCode = 200;String Msg = "消息信息保存成功";jsonResult = JsonResult.jsonReturn(statusCode, Msg, tabid);return jsonResult;} catch (Exception e) {msg = "接口调用异常";jsonResult = JsonResult.jsonWsReturn(1, msg, e.getMessage());LogService.getInstance(this).error("保存消息信息失败" + e.getMessage());String mg = "保存消息信息失败:" + e.getMessage();jsonResult = JsonResult.jsonReturnErr(mg);return jsonResult;}}

 

总结

以上是生活随笔为你收集整理的SSM+Druid实现动态多数据源切换(已实践)的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。