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
相关推荐
这主要通过`AbstractRoutingDataSource`类实现,该类能够根据某种策略(如事务ID、用户名等)动态决定当前操作所需的数据源。在配置中,我们可以定义多个数据源,并设置一个路由数据源来决定在哪个具体数据源上执行...
2. **配置动态数据源**:在Spring配置文件中,我们需要定义一个`AbstractRoutingDataSource`的子类实例,并为其设置数据源路由表。同时,还需要为每个实际数据源创建一个`DataSource` bean,并将它们添加到路由表中...
【Spring 动态数据源切换】使用 `AbstractRoutingDataSource` 的详细实现在处理多数据库环境时,Spring 提供了一个强大的工具 `AbstractRoutingDataSource`,它允许我们根据特定条件动态地切换数据源。本文将深入...
在Spring框架中,动态数据源实现是一个重要的特性,它允许应用程序根据特定的条件或用户需求在运行时切换数据源。这种灵活性对于多租户系统、数据隔离或者在不同环境(如开发、测试、生产)之间切换数据库配置尤其...
AbstractRoutingDataSource则是一个抽象类,它可以根据预定义的规则(如线程绑定、方法参数等)来动态选择数据源。在实际配置时,我们需要创建多个具体的DataSource实例,并将它们注册到Spring容器中,然后通过...
2. **使用AbstractRoutingDataSource**:Spring提供了一个抽象类`AbstractRoutingDataSource`,它可以基于某种条件(如线程绑定的变量)动态决定使用哪个数据源。我们需要创建一个自定义的DataSource,继承自`...
在Spring中,我们通常会创建一个`AbstractRoutingDataSource`的子类,这是一个特殊的数据源,它可以根据一定的规则(如线程绑定、请求参数等)动态地决定使用哪个底层数据源。 以下是一些核心知识点: 1. **`...
综上所述,Spring动态切换数据源是通过配置不同数据源,结合`AbstractRoutingDataSource`子类和`ThreadLocal`管理的策略,实现在运行时选择合适的数据源执行SQL操作。这一机制极大地增强了系统的灵活性和可扩展性。
- `AbstractRoutingDataSource`:这是Spring提供的核心类,用于动态路由数据源。它会根据某种策略(如事务ID、特定的标记等)决定使用哪个数据源。 - `DataSourceTransactionManager`:为每个数据源提供事务管理器...
Spring的`AbstractRoutingDataSource`可以帮助我们动态选择数据源,它可以根据预定义的规则(如请求参数、ThreadLocal等)来决定使用哪个数据源。 2. **集成Atomikos**:添加Atomikos依赖后,我们需要配置Atomikos...
Spring提供了多种方式来管理多数据源,例如通过`AbstractRoutingDataSource`实现动态数据源切换。这个类可以根据某些条件(如事务的标识、请求上下文等)动态决定使用哪个数据源。在`dynamicDatasourceDemo`项目中,...
使用注解配置实现Spring动态数据源切换,实现原理 1、自定义动态数据源类DynamicDataSource: 实现spring类AbstractRoutingDataSource的方法determineCurrentLookupKey 2、自定义Spring AOP类DataSourceAspect 3、...
2. **AbstractRoutingDataSource**:这是一个抽象的数据源类,它可以根据当前的上下文信息(如线程绑定的bean、请求参数等)动态决定使用哪个具体的数据源。通过扩展这个类或直接配置路由规则,我们可以实现数据源的...
DynamicDataSource是继承自AbstractRoutingDataSource抽象类的动态数据源实现类,该类的作用是根据配置参数创建数据源。DynamicDataSource类中定义了一个etermineCurrentLookupKey方法,该方法用于确定当前的数据源...
1. **配置数据源**:首先,你需要配置多个数据源,可以使用Spring的AbstractRoutingDataSource作为基础,该类可以根据某种路由策略(如线程本地变量、请求参数等)动态选择数据源。 2. **定义路由逻辑**:创建一个...
2. 使用Spring的AbstractRoutingDataSource作为基础数据源,它可以动态决定当前请求应使用哪个数据源。在运行时,AbstractRoutingDataSource会根据上下文信息(例如,自定义注解的值)来确定目标数据源。 3. 创建...
本示例代码将介绍如何在项目中配置和使用MyBatis-Plus实现多数据源和动态数据源切换。 首先,我们需要理解多数据源的概念。多数据源意味着系统中存在不止一个数据存储,每个数据源可能对应不同的数据库,如MySQL、...
接着,实现这个接口,基于Spring的`AbstractRoutingDataSource`,它是一个可扩展的抽象数据源,可以根据特定的规则动态决定使用哪个实际的数据源: ```java @Configuration public class DynamicDataSourceConfig {...
1. **配置动态数据源**:我们可以使用`AbstractRoutingDataSource`作为基础,这是一个Spring提供的类,它可以基于某种条件(如:注解、线程变量等)动态决定使用哪个具体的数据源。首先,创建一个自定义的`...
本主题聚焦于在Spring Cloud环境中实现多数据库和多数据源的整合,并且能够动态切换查询的数据库。这是一个复杂但至关重要的需求,特别是在大型企业级应用中,可能需要根据业务逻辑或用户权限连接到不同的数据库。 ...