- 浏览: 933009 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (251)
- WebService (17)
- IBatis (22)
- Hibernate (1)
- SpringMVC - 基础篇 (32)
- Spring (15)
- Java (11)
- JVM及调优 - 基础篇 (4)
- 集群 (14)
- 数据库 (17)
- WebSphere (5)
- 多线程 (4)
- 集合、容器 (2)
- DB Pool (1)
- Power Designer (5)
- Maven基础 (5)
- JS (14)
- WEB 前端 (5)
- 实用小工具 (17)
- 社会、人 (2)
- 乱七八糟 (18)
- ASM&CGLIB - 基础篇 (12)
- 缓存 (1)
- 性能 (1)
- 设计之殇 (1)
- 分布式事务 (1)
- 单点登录 (11)
- 分布式 Session (4)
- Memcached - 基础篇 (6)
最新评论
-
一笑_奈何:
楼主写的还真行不错。
扫盲贴 - J2EE集群之JNDI集群实现 -
xuezhongyu01:
博主写的很详细,但最后还是没明白,最后调用BasicDataS ...
Spring中的destroy-method方法 -
Mr梁:
commons-fileupload.jar commons- ...
SpringMVC 中文件上传 MultipartResolver -
Eywa:
总结的很不错
ORACLE CASE WHEN 及 SELECT CASE WHEN的用法 -
TryRelax:
fastjson 比 jackson 好用吧?
Spring MVC Jackson DateFormat
在Spring 2.0.1中引入了AbstractRoutingDataSource, 该类充当了DataSource的路由中介, 能有在运行时, 根据某种key值来动态切换到真正的DataSource上。
Spring动态配置多数据源,即在大型应用中对数据进行切分,并且采用多个数据库实例进行管理,这样可以有效提高系统的水平伸缩性。而这样的方案就会不同于常见的单一数据实例的方案,这就要程序在运行时根据当时的请求及系统状态来动态的决定将数据存储在哪个数据库实例中,以及从哪个数据库提取数据。
Spring对于多数据源,以数据库表为参照,大体上可以分成两大类情况:
一是,表级上的跨数据库。即,对于不同的数据库却有相同的表(表名和表结构完全相同)。
二是,非表级上的跨数据库。即,多个数据源不存在相同的表。
Spring2.x的版本中采用Proxy模式,就是我们在方案中实现一个虚拟的数据源,并且用它来封装数据源选择逻辑,这样就可以有效地将数据源选择逻辑从Client中分离出来。Client提供选择所需的上下文(因为这是Client所知道的),由虚拟的DataSource根据Client提供的上下文来实现数据源的选择。
具体的实现就是,虚拟的DataSource仅需继承AbstractRoutingDataSource实现determineCurrentLookupKey()在其中封装数据源的选择逻辑。
一、原理
首先看下AbstractRoutingDataSource类结构,继承了AbstractDataSource
public abstract class AbstractRoutingDataSource extends AbstractDataSource implements InitializingBean
既然是AbstractDataSource,当然就是javax.sql.DataSource的子类,于是我们自然地回去看它的getConnection方法:
public Connection getConnection() throws SQLException {
return determineTargetDataSource().getConnection();
}
public Connection getConnection(String username, String password) throws SQLException {
return determineTargetDataSource().getConnection(username, password);
}
原来关键就在determineTargetDataSource()里:
/**
* Retrieve the current target DataSource. Determines the
* {@link #determineCurrentLookupKey() current lookup key}, performs
* a lookup in the {@link #setTargetDataSources targetDataSources} map,
* falls back to the specified
* {@link #setDefaultTargetDataSource default target DataSource} if necessary.
* @see #determineCurrentLookupKey()
*/
protected DataSource determineTargetDataSource() {
Assert.notNull(this.resolvedDataSources, "DataSource router not initialized");
Object lookupKey = determineCurrentLookupKey();
DataSource dataSource = this.resolvedDataSources.get(lookupKey);
if (dataSource == null && (this.lenientFallback || lookupKey == null)) {
dataSource = this.resolvedDefaultDataSource;
}
if (dataSource == null) {
throw new IllegalStateException("Cannot determine target DataSource for lookup key [" + lookupKey + "]");
}
return dataSource;
}
这里用到了我们需要进行实现的抽象方法determineCurrentLookupKey(),该方法返回需要使用的DataSource的key值,然后根据这个key从resolvedDataSources这个map里取出对应的DataSource,如果找不到,则用默认的resolvedDefaultDataSource。
public void afterPropertiesSet() {
if (this.targetDataSources == null) {
throw new IllegalArgumentException("Property 'targetDataSources' is required");
}
this.resolvedDataSources = new HashMap<Object, DataSource>(this.targetDataSources.size());
for (Map.Entry entry : this.targetDataSources.entrySet()) {
Object lookupKey = resolveSpecifiedLookupKey(entry.getKey());
DataSource dataSource = resolveSpecifiedDataSource(entry.getValue());
this.resolvedDataSources.put(lookupKey, dataSource);
}
if (this.defaultTargetDataSource != null) {
this.resolvedDefaultDataSource = resolveSpecifiedDataSource(this.defaultTargetDataSource);
}
}
二、Spring配置多数据源的方式和具体使用过程
1、数据源的名称常量类
public enum DynamicDataSourceGlobal {
ORCL, ISC }
2、建立一个获得和设置上下文环境的类,主要负责改变上下文数据源的名称
public class DynamicDataSourceHolder {
// 线程本地环境 private static final ThreadLocal<DynamicDataSourceGlobal> contextHolder = new ThreadLocal<DynamicDataSourceGlobal>(); // 设置数据源类型 public static void setDataSourceType(DynamicDataSourceGlobal dataSourceType) { Assert.notNull(dataSourceType, "DataSourceType cannot be null"); contextHolder.set(dataSourceType); } // 获取数据源类型 public static DynamicDataSourceGlobal getDataSourceType() { return (DynamicDataSourceGlobal) contextHolder.get(); } // 清除数据源类型 public static void clearDataSourceType() { contextHolder.remove(); } }
3、建立动态数据源类,注意,这个类必须继承AbstractRoutingDataSource,且实现方法 determineCurrentLookupKey,该方法返回一个Object,一般是返回字符串
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override protected Object determineCurrentLookupKey() { return DynamicDataSourceHolder.getDataSourceType(); } }
4、编写spring的配置文件配置多个数据源
<!-- 数据源相同的内容 -->
<bean id="parentDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClass" value="oracle.jdbc.pool.OracleConnectionPoolDataSource" /> <property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl" /> <property name="user" value="isc_v10" /> <property name="password" value="isc" /> </bean> <!-- 数据源 --> <bean id="orclDataSource" parent="parentDataSource"> <property name="user" value="orcl" /> <property name="password" value="orcl" /> </bean> <!-- 数据源 --> <bean id="iscDataSource" parent="parentDataSource"> <property name="user" value="isc_v10" /> <property name="password" value="isc" /> </bean> <!-- 编写spring 配置文件的配置多数源映射关系 --> <bean id="dataSource" class="com.wy.config.DynamicDataSource"> <property name="targetDataSources"> <map key-type="java.lang.String"> <entry key="ORCL" value-ref="orclDataSource"></entry> <entry key="ISC" value-ref="iscDataSource"></entry> </map> </property> <property name="defaultTargetDataSource" ref="orclDataSource"> </property> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> </bean>
5、使用
@Test
public void testSave() { // hibernate创建实体 DynamicDataSourceHolder.setDataSourceType(DynamicDataSourceGlobal.ORCL);// 设置为另一个数据源 com.wy.domain.Test user = new com.wy.domain.Test(); user.setName("WY"); user.setAddress("BJ"); testDao.save(user);// 使用dao保存实体 DynamicDataSourceHolder.setDataSourceType(DynamicDataSourceGlobal.ISC);// 设置为另一个数据源 testDao.save(user);// 使用dao保存实体到另一个库中 }
评论
这个只是实现了同一个数据库,不同数据库实例的切换
如果你的方法在事务监控中,这种方式是不能切换数据源的。
这个只是实现了同一个数据库,不同数据库实例的切换
发表评论
-
properties 文件 属性值换行
2013-09-24 16:33 2205在项目开发中遇到属性文件propertie ... -
扩展PropertyPlaceholderConfigurer对prop文件中的属性加密
2013-09-24 13:53 7153转载:http://my.oschina.net/noah ... -
精通有状态vs无状态(Stateful vs Stateless)—Immutable模式之姐妹篇
2013-09-10 18:06 2230今天给别人解释 Stateful vs Stateless ... -
Spring的DTD验证
2013-03-28 15:45 3823转载:http://a123159521.iteye. ... -
用spring annotation声明的bean,当打包在jar中时,无法被扫描到
2012-10-16 16:33 1274我们项目是由N个工程组成的,外围工程是web工程,内部的工程打 ... -
what’s new in spring 3
2012-10-15 21:35 1234spring3发布已经很久了,但现在为止还不太清楚spring ... -
利用AbstractRoutingDataSource实现动态数据源切换(Spring+Ibatis)
2012-10-14 15:49 3549Spring+Ibatis 与 Spring+Hibernat ... -
利用AbstractRoutingDataSource实现动态数据源切换 (二、Spring+Hibernate)
2012-10-14 13:55 2818用spring 的AbstractRoutingData ... -
Spring中的destroy-method方法
2012-05-20 12:29 22093转载:http://technoboy.iteye.com/b ... -
Spring事务(一)
2012-02-26 17:48 991一、Spring中定义了5中不同的事务隔离级别 1 ... -
Spring容器启动过程
2011-09-17 22:58 1835一、一切从手动启动IoC ... -
Spring AOP续
2011-09-03 16:37 1454三 AOP的实现方式---Proxy Spring默认使用J2 ... -
Spring AOP
2011-09-03 15:35 1441前段时间使用AOP做日志拦截,由于很长时间没有使用过 ... -
Web开发中获取Spring的ApplicationContext的几种方式
2011-08-24 21:49 11985在 WEB 开发中,获取到由 Spring 进行管理的某些 B ...
相关推荐
Spring提供了AbstractRoutingDataSource类,允许我们根据某种规则(如事务、请求上下文等)动态切换数据源。我们需要扩展这个类,并实现determineCurrentLookupKey方法来决定当前应该使用哪个数据源。 接着,描述中...
"spring+hibernate和spring+myBatis实现连接多个数据库,同时操作的项目"是针对这种需求的一个解决方案,旨在提供一种灵活且动态的数据源切换机制。 首先,Spring框架作为Java领域中最受欢迎的应用框架之一,其强大...
【Spring 动态数据源切换】使用 `AbstractRoutingDataSource` 的详细实现在处理多数据库环境时,Spring 提供了一个强大的工具 `AbstractRoutingDataSource`,它允许我们根据特定条件动态地切换数据源。本文将深入...
在Spring配置文件中,我们可以通过配置`AbstractRoutingDataSource`类来实现动态数据源切换。这个类可以根据一定的规则动态选择数据源。例如: ```xml <bean id="dataSource" class="org.springframework.jdbc....
本项目“spring 3.29+struts2.3.15.1+hibernate3 动态切换数据源”正是针对这一需求,通过整合Spring、Struts2和Hibernate3这三大经典Java EE框架,实现了数据源的灵活配置和动态切换。 首先,Spring作为Java应用中...
本项目"一套Spring+Hibernate的多个数据库切换的源码"提供了一个实现这一功能的示例,它利用了Spring框架的强大功能和Hibernate的持久化能力,实现了灵活的数据源切换。 首先,Spring框架是Java开发中最常用的应用...
DataSourceTransactionManager用于管理数据库事务,而AbstractRoutingDataSource则允许动态选择数据源,从而实现切换到不同的数据库。 其次,Hibernate 4是一个流行的ORM(对象关系映射)工具,它简化了Java应用与...
这些代码可以直接集成到你的项目中,只需要调整为匹配你的数据库配置,就可以实现Spring Boot 2下的多数据源支持,同时利用Hibernate和MyBatis的优势。 总之,多数据源的实现是Spring Boot 2应用中的高级特性,它...
本知识点主要探讨如何在Spring中集成Hibernate来实现多数据源的动态切换功能,这对于需要处理多种数据源的应用来说至关重要。 首先,我们需要理解什么是多数据源。多数据源意味着一个应用程序可以连接并操作多个...
2. 配置多数据源路由:SpringBoot提供了AbstractRoutingDataSource,可以根据业务逻辑动态切换数据源。例如,可以通过事务的隔离级别、方法的注解等方式决定使用哪个数据源。 3. 实现DAO层:在Hibernate的实体类和...
SSH动态切换数据源是一种在Java Web开发中处理多数据库连接切换的技术,主要应用于Spring、Struts和Hibernate(SSH)这三大框架集成的项目。SSH框架是企业级应用开发的常用组合,提供了强大的业务逻辑处理和数据持久...
总结来说,Spring Boot实现多数据源的关键在于正确配置多个数据源,创建相应的事务管理器,并在业务代码中灵活地切换和使用这些数据源。通过这种方式,我们可以充分利用多个数据库的资源,提升系统的扩展性和可靠性...
Spring框架的多数据源动态切换是一项关键功能,尤其在处理大型应用中,它允许系统根据需求灵活地在多个数据库之间切换,以实现更好的负载均衡和数据管理。在本文中,我们将深入探讨如何在Spring中配置和使用动态数据...
5. **配置数据源路由**:使用Spring的AbstractRoutingDataSource实现动态数据源选择。根据业务逻辑,它可以在运行时决定使用哪个数据源。 ```java public class DynamicDataSource extends ...
Spring提供了一个名为`BasicDataSource`的类,它实现了`javax.sql.DataSource`接口,是最基础的数据源配置。在没有特殊需求的情况下,可以使用`BasicDataSource`。配置时,需要设置数据库URL、用户名、密码等属性。...
也可以创建一个路由数据源(如`AbstractRoutingDataSource`),它可以根据特定的规则(如事务上下文、方法参数等)动态决定使用哪个实际的数据源。 4. **JdbcTemplate与NamedParameterJdbcTemplate**:Spring提供的...
Spring多数据源解决方案是针对大型应用中数据分片和分布式数据库管理的需求而设计的一种策略。在这样的场景下,为了提高系统的可扩展性和性能,数据通常会被分散到多个数据库实例上。这种架构如图1所示,每个数据库...
`DynamicDataSource.java`文件可能是自定义的数据源切换器,它继承自Spring的`AbstractRoutingDataSource`,这个类允许我们在运行时根据某些条件(比如方法注解)动态选择数据源。你需要在这个类中实现`...
在Spring框架中实现多个数据源的注入,主要是为了解决项目中需要连接并动态切换不同数据库的需求。这种需求通常出现在多租户系统或者需要对不同客户提供差异化服务的场景。以下是一种基于Decorator设计模式的解决...
总之,Java中的多数据源切换是一个复杂但重要的功能,它涉及到SpringMVC、MyBatis或Hibernate等技术的深度整合。通过合理配置和智能路由,我们可以实现数据库的动态切换,满足不同场景下的数据访问需求。在具体实现...