Spring多数据源的配置和使用(1)

      最近开发一个数据同步的小功能,需要从A主机的Oracle数据库中把数据同步到B主机的Oracle库中。当然能够用dmp脚本或者SQL脚本是最好,但是对于两边异构的表结构来说,直接导入不可行。然后在需要实时同步的情况下用存储过程也不可行了。写一个数据同步的小程序是个不错的选择。使用框架的封装和连接池是必须的,Spring是首选,这里我们同样需要Spring的多数据源连接配置方式。 其实再进行项目开发的时候,一个项目有可能不止用到一个数据源,为了提高数据库的水平伸缩性,需要对多个数据库实例进行管理,需要配置多数据源。

 

     本文以Spring2.5 + Oracle10g 为例配置和使用多数据源。

 

     1. 配置多个数据源

     这里以两个c3p0数据库连接池的数据源作为实例。在Spring框架下使用c3p0的数据库需要加入c3p0-0.9.1.2.jar (现在最新的)这个支持包。这里以数据同步项目为例:

   数据来源库的连接池数据源配置:

<bean id="dataSourceFrom" class="com.mchange.v2.c3p0.ComboPooledDataSource">
	<property name="driverClass" value="${jdbc.driver}" />
	<property name="jdbcUrl" value="${jdbc.from.url}" />
	<property name="user" value="${jdbc.from.username}" />
	<property name="password" value="${jdbc.from.password}" />
	<property name="autoCommitOnClose" value="true" />
	<property name="checkoutTimeout" value="${cpool.checkoutTimeout}" />
	<property name="initialPoolSize" value="${cpool.minPoolSize}" />
	<property name="minPoolSize" value="${cpool.minPoolSize}" />
	<property name="maxPoolSize" value="${cpool.maxPoolSize}" />
	<property name="maxIdleTime" value="${cpool.maxIdleTime}" />
	<property name="acquireIncrement" value="${cpool.acquireIncrement}" />
	<property name="maxIdleTimeExcessConnections" value="${cpool.maxIdleTimeExcessConnections}" />
</bean>

 数据插入库的连接池数据源配置:

<bean id="dataSourceTo" class="com.mchange.v2.c3p0.ComboPooledDataSource">
	<property name="driverClass" value="${jdbc.driver}" />
	<property name="jdbcUrl" value="${jdbc.to.url}" />
	<property name="user" value="${jdbc.to.username}" />
	<property name="password" value="${jdbc.to.password}" />
	<property name="autoCommitOnClose" value="true" />
	<property name="checkoutTimeout" value="${cpool.checkoutTimeout}" />
	<property name="initialPoolSize" value="${cpool.minPoolSize}" />
	<property name="minPoolSize" value="${cpool.minPoolSize}" />
	<property name="maxPoolSize" value="${cpool.maxPoolSize}" />
	<property name="maxIdleTime" value="${cpool.maxIdleTime}" />
	<property name="acquireIncrement" value="${cpool.acquireIncrement}" />
	<property name="maxIdleTimeExcessConnections" value="${cpool.maxIdleTimeExcessConnections}" />
</bean>

   注意:上面url,user,password等值是从classpath下的jdbc.properties中取得的。

   通过Spring获取属性文件中的值,以供配置文件使用:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
	<property name="locations" value="classpath:jdbc.properties" />
</bean>

 

     2. 扩展Spring的AbstractRoutingDataSource抽象类,实现动态数据源。

    AbstractRoutingDataSource中的抽象方法determineCurrentLookupKey是实现数据源的route的核心.这里对该方法进行Override。

public class DynamicDataSource extends AbstractRoutingDataSource{

	@Override
	protected Object determineCurrentLookupKey() {
		return DBContextHolder.getDBType();
	}
}

   上下文DbContextHolder为一线程安全的ThreadLocal,具体代码如下:

public class DBContextHolder{
	public static final String DATA_SOURCE_FROM = "dataSourceFrom";
	public static final String DATA_SOURCE_TO = "dataSourceTo";
	
	private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
	
	public static void setDBType(String dbType) {
		contextHolder.set(dbType);
	}
	
	public static String getDBType() {
		return contextHolder.get();
	}
	
	public static void clearDBType() {
		contextHolder.remove();
	}
}

 

    3.配置动态数据源

 将DynamicDataSource Bean加入到Spring的上下文xml配置文件中去,同时配置DynamicDataSource的targetDataSources(多数据源目标)属性的Map映射。

<bean id="dynamicDataSource" class="datasource.DynamicDataSource" >
	<!-- 通过key-value的形式来关联数据源 -->
	<property name="targetDataSources">
		<map>
			<entry value-ref="dataSourceFrom" key="dataSourceFrom"></entry>
			<entry value-ref="dataSourceTo" key="dataSourceTo"></entry>
		</map>
	</property>
	<property name="defaultTargetDataSource" ref="dataSourceFrom" />
</bean> 

 

    4.使用动态数据源

    例子中DynamicDataSource是继承与AbstractRoutingDataSource,而AbstractRoutingDataSource又是继承于org.springframework.jdbc.datasource.AbstractDataSource,AbstractDataSource实现了统一的DataSource接口,所以DynamicDataSource同样可以当一个DataSource使用。

 在Spring的JdbcTemplate使用动态数据源的配置示例:

<!-- JdbcTemplate使用动态数据源的配置 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
	<property name="dataSource">
		<ref bean="dynamicDataSource" />
	</property>
</bean>

<!-- 对JdbcTemplate的应用封装类 -->
<bean id="sqlBaseDAO" class="com.whty.dao.BaseDAOImpl">
	<property name="jdbcTemplate">
		<ref bean="jdbcTemplate" />
	</property>
</bean>


    5.事务管理

使用动态数据源的时候,可以看出和使用单数据源的时候相比,在使用配置上几乎没有差别,在进行性事务管理配置的时候也没有差别:

使用Spring的JdbcTemplate的事务管理配置示例:

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<property name="dataSource" ref="dynamicDataSource" />
</bean>

<bean id="sqlBaseDAOProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
	<property name="transactionManager" ref="transactionManager" />
	<property name="target" ref="sqlBaseDAO" />
	<property name="transactionAttributes">
		<props>
			<prop key="insert*">PROPAGATION_REQUIRED</prop>
			<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
		</props>
	</property>
</bean>
  

    6.动态数据源的管理控制

如何选择控制每个业务中需要的具体数据源,可是使用手动控制:

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
BaseDAO dao = (BaseDAO) context.getBean("sqlBaseDAO", BaseDAOImpl.class);

try {
	DBContextHolder.setCustomerType(DBContextHolder.DATA_SOURCE_FROM);
	System.err.println(dao.select("select count(*) sum from TEST t ").get(0).get("SUM"));
	DBContextHolder.setCustomerType(DBContextHolder.DATA_SOURCE_TO);
	System.err.println(dao.select("select count(*) sum from TEST t ").get(0).get("SUM"));
	
} catch (Exception e) {
	e.printStackTrace();
}

也可以采用AOP的控制方式:

@Aspect
public class DynamicDataSourceAspect {
	@Pointcut("execution (public service.impl..*.*(..))")
	public void serviceExecution(){}
	
	@Before("serviceExecution()")
	public void setDynamicDataSource(JoinPoint jp) {
		for(Object o : jp.getArgs()) {
			//处理具体的逻辑 ,根据具体的境况CustomerContextHolder.setCustomerType()选取DataSource
		}
	}
}

 

  7.总结

   通过扩展Spring的AbstractRoutingDataSource可以很好的实现多数据源的rout效果,而且对扩展更多的数据源有良好的伸缩性,只要增加数据源和修改DynamicDataSource的targetDataSources属性配置就好。在数据源选择控制上,可以采用手动控制(业务逻辑并不多的时候),也可以很好的用AOP的@Aspect在Service的入口加入一个切面@Pointcut,在@Before里判断JoinPoint的类容选定特定的数据源。

 

 

 

参考:

1.KindAzrael的BLOG《Spring多数据源的配置

2.xiaoZ5919的BLOG《 jdbctemplate与事务管理

 


文中代码项目在下一篇BLOG《Spring定时任务的多种使用方法总结 》的附件中。

扫地机器人全场景测试实战:从实验室到真实家庭的可靠性验证 本文深入探讨了扫地机器人从实验室到真实家庭的全场景测试方法,揭示了软硬件测试中的关键挑战。通过分析场景化测试的重要性,文章详细介绍了硬件耐久性、软件稳定性环境适应性三大测试维度,并提供了真实家庭测试的实用方法论。消费者可重点关注清洁率、覆盖率等核心指标,同时了解测试工程师的私房建议,帮助选择更可靠的扫地机器人产品。 阅读详情

相关推荐

ABB机器人ModbusTCP通信实战:如何高效传输Float数据到PLC(附完整代码)

本文详细介绍了ABB机器人通过ModbusTCP协议高效传输Float数据到PLC的实战方法,包括底层逻辑解析、RAPID程序架构设计、PLC服务器配置及现场调试技巧。特别针对浮点数据传输中的字节顺序问题提供了解决方案,并附有完整代码示例,助力工程师快速实现工业自动化设备间的高精度数据交互。

weixin_30836759的博客 458

SpringBoot根据包名进行区分使用多数据源

就是让一个项目应用并使用多个数据库,这里采用的是SpringBoot2.0、MySql5.7,使用两个两个MySql数据库 1、建立两个数据库 2、建立一个SpringBoot项目 3、Pom文件 <?xml version="1.0" encoding="UTF-8"?><project...

s_156的博客 1096

Spring MVC 3与MyBatis结合JTA及JBoss 7.1实现多数据源配置详解

注解是一种元数据的形式,可以用于提供指令给编译器其他工具。在Spring MVC中,注解通常用于简化配置、实现依赖注入处理请求映射等功能。其在Web开发中的重要性体现在通过注解快速定义控制器、服务数据模型等组件,从而实现松耦合代码的自动化管理。");上述代码中,@Controller注解标识了一个类作为控制器组件,而@RequestMapping则定义了一个方法级别的映射,指定了访问路径”/hello”对应的方法。

weixin_30765637的博客 473

SpringBoot 多数据源切换(二)(依旧超级简单)

背景:主从架构下,数据库的读写分离

Tz.的博客 1086

SpringBoot多数据源查询(注解方式)

2、创建SpringBoot项目。1、准备两个数据源(如下图:)

m0_38029796的博客 1525

SpringBoot多数据源配置

springboot项目多数据源简单实现

qq_30114599的博客 950

springMVC+c3p0多数据源配置

//数据源公用设置     &lt;bean id="dataSource" name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"&gt;           &lt;!-- 指定连接数据库的驱动--&gt;           &lt;property name="driverClass" value=&

张凡 1480

纯干货 Spring boot 2.1 JPA多数据源配置

Spring boot 从1.5到2.0到2.1 版本不停的更新。多数据源配置每次都会改变。最新的spring boot2.1多数据源配置方式请参照下面介绍 环境 spring boot 2.1 druid 1.1.14 mysql application.properties配置(参数自己补齐) spring.datasource.primary.url=url spring.datasour...

3105

spring基于通用Dao的多数据源配置详解【ds1

spring基于通用Dao的多数据源配置详解 有时候在一个项目中会连接多个数据库,需要在spring配置多个数据源,最近就遇到了这个问题,由于我的项目之前是基于通用Dao的,配置的时候问题不断,这种方式资源文件冲突;扫描映射文件的话,SqlSessionFactory的bean名字必须是sqlSessionFactory 他读不到sqlSessioNFactor...

weixin_30455067的博客 306

Spring Boot 1.0多数据源配置

Spring Boot 1.x下,我们的多数据源配置如下: 读数据库 @Configuration @EnableTransactionManagement @EnableJpaRepositories(entityManagerFactoryRef = &amp;quot;entityManagerFactoryPrimary&amp;quot;, transactionManagerRef = &amp;quot;transactionMa...

helloworld的专栏 898

六、spring boot 1.5.4 配置多数据源

spring boot 已经支持多数据源配置了,无需网上好多那些编写什么类的,特别麻烦,看看如下解决方案,官方的,放心! 1.首先定义数据源配置 #=====================mul...

setsunadoudou的博客 139

【Mongo】spring-data-mongodb3.1.3配置多数据源

1.项目框架介绍:springboot集成spring-data-mongodb3.1.3 (内嵌mongo-driver-core4.1.1) 2.配置文件:application.yml mongodb: primary: host: 192.168.1.1 port: 27017 database: database1 username: ceshi1 password: ceshi12345 secondary: host: 192.16

嘻嘻哈哈 1483

11Spring Boot系列之多数据源配置(方法1

Spring Boot 1 多数据源可以参考: https://www.cnblogs.com/chenliangcl/p/7346020.html Spring Boot 2 多数据源配置参考: https://www.cnblogs.com/caichaoqi/p/9216865.html

ˉ-_lishk_-ˉ 387

Spring Boot教程(三十二)多数据源配置使用1

之前在介绍使用JdbcTemplateSpring-data-jpa时,都使用了单数据源。在单数据源的情况下,Spring Boot的配置非常简单,只需要在application.properties文件中配置连接参数即可。但是往往随着业务量发展,我们通常会进行数据库拆分或是引入其他数据库,从而我们需要配置多个数据源,下面基于之前的JdbcTemplateSpring-data-jp...

dhpu15386的博客 141

spring ibatis 多数据源 事务配置

网上找的,spring+ibatis+struts1.2 的多数据源事务配置。没试过。先做下记录。 jdbc.properties文件内容: jdbc2.driverClassName=net.sourceforge.jtds.jdbc.Driver jdbc2.url=jdbc:jtds:sqlserver://10.101.122.9:1433/testdb;charset=gb23...

benbenxiongyuan的专栏 217

Spring Boot 1.0 && 2.0 + JPA 多数据源配置使用

环境说明 Spring Boot 1.5.17.RELEASE 或 Spring Boot 2.1.0.RELEASE MySQL v5.6.19 PostgreSQL v10.4 无特殊说明,以下所说的环境均指 Spring Boot 2.1.0.RELEASE,如果使用的是 Spring Boot 1.5.17.RELEASE 这个版本,只需要调整下面有做说明的几处地方 连接配置 ...

happyJared 606

Spring Boot 2.1.1.RELEASE 多数据源配置使用

有时候,一个系统的功能,需要两个或两个以上的数据库, 在Spring Boot 中要如何配置? How to? #primary primary.spring.datasource.jdbc-url=jdbc:mysql://localhost:3316/test1 primary.spring.datasource.username=root primary.spring.data...

weixin_34062329的博客 112

Spring Boot 2.x基础教程:JdbcTemplate多数据源配置

添加多数据源配置 先在Spring Boot的配置文件application.properties中设置两个你要链接的数据库配置,比如这样: spring.datasource.primary.jdbc-url=jdbc:mysql://localhost:3306/test1 spring.datasource.primary.username=root spring.datasource.primary.password=123456 spring.datasource.primary.driver-

m0_45270667的博客 4877

boot jpa mysql postman spring_Spring Boot 1.0&&2.0 + JPA 多数据源配置使用

环境说明Spring Boot 1.5.17.RELEASE 或 Spring Boot 2.1.0.RELEASEMySQL v5.6.19PostgreSQL v10.4无特殊说明,以下所说的环境均指 Spring Boot 2.1.0.RELEASE,如果使用的是 Spring Boot 1.5.17.RELEASE 这个版本,只需要调整下面有做说明的几处地方连接配置在application...

weixin_32139249的博客 77

光伏电站发电量预测数据集(17500条数据)

训练数据集:光伏发电设备采集信息9000条; 测试数据集:光伏发电设备采集信息8500条。 使用说明:文件中包含以下内容: 表格字段及含义如下: ID:当前记录条数; 板温:光伏电池板背测温度; 现场温度:光伏电站现场温度; 转换效率:为计算得到的平均转换效率; 转换效率A:数据采集点A处的光伏板转换效率; 转换效率B:数据采集点B处的光伏板转换效率; 转换效率C:数据采集点C处的光伏板转换效率; 转换效率D:数据采集点D处的光伏板转换效率; 电压A:为数据采集点A处汇流箱电压值; 电压B:为数据采集点B处汇流箱电压值; 电压C:为数据采集点C处汇流箱电压值; 电压D:为数据采集点D处汇流箱电压值;等等

上一篇: Struts2的标签显示日期、<s:debug>标签、<s:property>使用技巧
下一篇: Spring定时任务的多种使用方法总结
ganking12
博客等级 码龄17年 3粉丝 61原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值