Spring动态配置多数据源,即在大型应用中对数据进行横向切分,并且采用多个数据库实例进行管理,这样可以有效提高系统的水平伸缩性。而这样的方案就会不同于常见的单一数据实例的方案,这就要程序在运行时根据当时的请求及系统状态来动态的决定将数据存储在哪个数据库实例中,以及从哪个数据库提取数据。
Spring配置多数据源的方式和具体使用过程。
Spring对于多数据源,以数据库表为参照,大体上可以分成两大类情况:
一是,表级上的跨数据库。即,对于不同的数据库却有相同的表(表名和表结构完全相同)。
二是,非表级上的跨数据库。即,多个数据源不存在相同的表。
Spring2.x的版本中采用Proxy模式,就是我们在方案中实现一个虚拟的数据源,并且用它来封装数据源选择逻辑,这样就可以有效地将数据源选择逻辑从Client中分离出来。Client提供选择所需的上下文(因为这是Client所知道的),由虚拟的DataSource根据Client提供的上下文来实现数据源的选择。
具体的实现就是,虚拟的DataSource仅需继承AbstractRoutingDataSource实现determineCurrentLookupKey()在其中封装数据源的选择逻辑。
步骤如下:
一、动态配置多数据源
1. 数据源的名称常量类:
package com.frogking.datasource; public class DataSourceConst { public static final String Admin="admin"; public static final String User = "user"; }
2. 建立一个获得和设置上下文环境的类,主要负责改变上下文数据源的名称:
package com.frogking.datasource; package com.frogking.datasource; public class DataSourceContextHolder { private static final ThreadLocal contextHolder = new ThreadLocal(); // 线程本地环境 // 设置数据源类型 public static void setDataSourceType(String dataSourceType) { contextHolder.set(dataSourceType); } // 获取数据源类型 public static String getDataSourceType() { return (String) contextHolder.get(); } // 清除数据源类型 public static void clearDataSourceType () { contextHolder.remove(); } }
3. 建立动态数据源类,注意,这个类必须继承AbstractRoutingDataSource,且实现方法 determineCurrentLookupKey,该方法返回一个Object,一般是返回字符串:
package com.frogking.datasource; package com.frogking.datasource; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; public class DynamicDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return DataSourceContextHolder.getDataSourceType(); } }
4. 编写spring的配置文件配置多个数据源
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <!-- 数据源相同的内容 --> <bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="parentDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"> </property> <property name="username"> <value>root</value> </property> <property name="password"> <value>root</value> </property> </bean> <!-- 数据库test --> <bean parent="parentDataSource" id="adminDataSource"> <property name="url"> <value>jdbc:mysql://localhost:8806/test</value> </property> </bean> <!-- 数据库test1 --> <bean parent="parentDataSource" id="userDataSource"> <property name="url"> <value>jdbc:mysql://localhost:8906/test2</value> </property> </bean> <!-- 编写spring 配置文件的配置多数源映射关系 --> <bean class="com.frogking.datasource.DynamicDataSource" id="dataSource"> <property name="targetDataSources"> <map key-type="java.lang.String"> <entry value-ref="adminDataSource" key="admin"></entry> <entry value-ref="userDataSource" key="user"></entry> </map> </property> <property name="defaultTargetDataSource" ref="adminDataSource"> </property> </bean> <!-- sessionFactory的配置 --> <bean class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" id="sessionFactory"> <property name="dataSource"> <ref local="dataSource"></ref> </property> <!-- 实体映射资源 --> <property name="mappingResources"> <list> <value>com/frogking/entity/User.hbm.xml</value> <value>com/frogking/entity/Admin.hbm.xml</value> </list> </property> <!-- 为sessionFactory配置Hibernate属性 --> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect"> org.hibernate.dialect.MySQLDialect </prop> <prop key="hibernate.show_sq">true</prop> <prop key="hibernate.connection.autocommit">false</prop> <prop key="hibernate.cache.use_query_cache">false</prop> <prop key="hibernate.max_fetch_depth">2</prop> <prop key="hibernate.bytecode.use_reflection_optimizer"> true </prop> </props> </property> </bean> <bean id="userDao" class="com.frogking.dao.impl.UserDaoImpl"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> </beans>
六。写dao层
七。编写测试类测试是否成功
package com.frogking.test; import static org.junit.Assert.fail; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.frogking.dao.IUserDao; import com.frogking.datasource.DataSourceConst; import com.frogking.datasource.DataSourceContextHolder; import com.frogking.entity.User; public class UserTest { ApplicationContext ac= new ClassPathXmlApplicationContext("applicationContext.xml"); IUserDao userDao =(IUserDao)ac.getBean("userDao"); @Test public void testSave() { //hibernate创建实体 DataSourceContextHolder.setDataSourceType(DataSourceConst.Admin);//设置为另一个数据源 User user=new User(); user.setName("user001"); user.setPassword("001"); userDao.save(user);//使用dao保存实体 DataSourceContextHolder.setDataSourceType(DataSourceConst.User);//设置为另一个数据源 userDao.save(user);//使用dao保存实体到另一个库中 } }
参考:http://blog.springsource.com/2007/01/23/dynamic-datasource-routing
相关推荐
本篇文章主要介绍了详解Spring(AbstractRoutingDataSource)实现动态数据源切换,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
使用注解配置实现Spring动态数据源切换,实现原理 1、自定义动态数据源类DynamicDataSource: 实现spring类AbstractRoutingDataSource的方法determineCurrentLookupKey 2、自定义Spring AOP类DataSourceAspect 3、...
SpringBoot2.x 继承 AbstractRoutingDataSource 动态数据源切换实现 JPA读写分离。 使用MyCat代理MySQL8数据库,添加root账户(读写)和user账户(只读)模拟读写简单分离。
spring+druid+AtomikosDataSource实现多数据源切换及分布式事务控制
主要介绍了使用Spring的AbstractRoutingDataSource实现多数据源切换示例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
本篇文章主要介绍了详解利用Spring的AbstractRoutingDataSource解决多数据源的问题。具有一定的参考价值,有兴趣的可以了解一下。
MySQL Master Slave 集群构架和spring整合,里面实现的是动态切换数据源,大家都是知道,spring2之后添加AbstractRoutingDataSource这个东西,这个就可以实现切换数据源,实现思路是:先按照搭建MySQL的MasterSlave...
`ThreadLocal` 是 Java 中的一个类,用于存储线程局部变量。线程局部变量与普通的变量不同,它不是共享的,每个线程...结合 `ThreadLocal` 和 `AbstractRoutingDataSource`,我们可以轻松地在运行时动态地切换数据源。
本篇文章主要介绍了浅谈利用Spring的AbstractRoutingDataSource解决多数据源的问题,具有一定的参考价值,有需要的可以了解一下
Spring Boot整合Mybatis使用druid实现多数据源自动切换
基于Spring的 AbstractRoutingDataSource 进行简单的封装,方便进行数据源的切换,目前主要用于主从数据库的读写切换上。切换spring数据源的工具,使用aop注解方式进行快速切换,减少编码的入侵
spring +springboot+mybatis+maven 读写分离,数据库采用mysql, 采用springboot 采用项目框架搭建,继承spring 中的AbstractRoutingDataSource,实现 determineCurrentLookupKey 进行数据源的动态切换,采用Spring ...
主从数据源切换(两个版本)一是利用Spring提供的AbstractRoutingDataSource,二是使用自定义数据源切换类 模块 actdemo ├── mybatisGenerator --mybatis生成程序 └── web --SpringBoot项目 集成activiti6.0.0...
基于Enable驱动的spring boot多数据源配置的实现,主要运用了spring的AbstractRoutingDataSource和aop
《在Sping Cloud(Spring Boot)中基于AbstractRoutingDataSource 实现多数据源动态切换》多数据源元数据存储表,在postgres数据库可直接运行,如果是别的数据库请自行修改sql语句
这是一个轻量级分库分表框架&读写分离框架,无需搭建中间层代理服务,开发者只需要引入本框架的jar包,并进行相应的配置即可实现分库...开发者只需要根据自身的数据源信息组装好此数据源,在此框架中定义了一个DataSo
--利用AbstractRoutingDataSource实现动态数据源切换 --> 数据源 <!-- write --> <!-- read --> <!-- 从org.springframework.jdbc.datasource.lookup....
Spring boot + Mybatis + alibaba druid通过继承AbstractRoutingDataSource的determineCurrentLookupKey来动态切换DataSource,主从切换,读写分离。 可以直接运行,完整工程代码 + SQL脚本。