- 浏览: 2473474 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (574)
- Book (62)
- Architecture (6)
- Java (39)
- Taobao (41)
- Distributed (4)
- Life (72)
- Database (7)
- Spring (16)
- Photography (15)
- Bicycle (41)
- Test (20)
- jBPM (8)
- Business (12)
- Movie (3)
- Ajax (15)
- Code (7)
- Eclipse (96)
- VIM (2)
- Music (6)
- Groovy (10)
- AutoHotKey (3)
- Dorado (10)
- Maven (7)
- Scrum (5)
- English (20)
- Financial (12)
- OSGi (3)
- Other (4)
- Tool (6)
- Browser (1)
- PPT (1)
- Project Management (4)
- Agile (6)
- Nosql (1)
- Search engine (6)
- Shell (2)
- Open Source (4)
- Storm (10)
- Guava (3)
- Baby (1)
- netty (1)
- Algorithm (1)
- Linux (1)
- Python (2)
最新评论
-
roy2011a:
https://github.com/ebottabi/sto ...
storm的序列化问题及与spring的结合方式 -
roy2011a:
能抗能打 写道哥们儿,你好!能共享下那个storm与sprin ...
storm的序列化问题及与spring的结合方式 -
Alick1:
兄弟,你之前是不是在深圳的正阳公司呆过啊?
storm的ack和fail -
liuleixwd:
先点个赞,写的非常好!有个问题请教下,如果我再bolt里不用e ...
storm的ack和fail -
yao-dd:
solr的facet查询
简单的翻译, 也算是一篇笔记.
原文:http://blog.springsource.com/2007/01/23/dynamic-datasource-routing/
在Spring 2.0.1中引入了AbstractRoutingDataSource, 该类充当了DataSource的路由中介, 能有在运行时, 根据某种key值来动态切换到真正的DataSource上, 同时对于不支持事务隔离级别的JTA事务来说, Spring还提供了另外一个类IsolationLevelDataSourceRouter来处理这个问题. 下面的例子将通过context来切换不同的数据源.
首先定义一个Catalog的Dao:
然后定义一个Item的JavaBean
接着定义一个枚举类型, 用来表示不同的用户级别, 通过该类型将映射到不同的数据源
下面是DataSource定义:
AbstractRoutingDataSource 实现类
CustomerContextHolder 是一个和LocalThread绑定的类, 定义如下:
将dao bean和datasource bean结合起来, 至于dao和真正的datasource如何关联这个可以根据需要指定相关的策略和规则来实现:
下面通过一个TestCase来看看如何使用:
原文:http://blog.springsource.com/2007/01/23/dynamic-datasource-routing/
在Spring 2.0.1中引入了AbstractRoutingDataSource, 该类充当了DataSource的路由中介, 能有在运行时, 根据某种key值来动态切换到真正的DataSource上, 同时对于不支持事务隔离级别的JTA事务来说, Spring还提供了另外一个类IsolationLevelDataSourceRouter来处理这个问题. 下面的例子将通过context来切换不同的数据源.
首先定义一个Catalog的Dao:
package blog.datasource; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; import org.springframework.jdbc.core.simple.ParameterizedRowMapper; import org.springframework.jdbc.core.simple.SimpleJdbcDaoSupport; public class Catalog extends SimpleJdbcDaoSupport { public List<Item> getItems() { String query = "select name, price from item"; return getSimpleJdbcTemplate().query(query, new ParameterizedRowMapper<Item>() { public Item mapRow(ResultSet rs, int row) throws SQLException { String name = rs.getString(1); double price = rs.getDouble(2); return new Item(name, price); } }); } }
然后定义一个Item的JavaBean
package blog.datasource; public class Item { private String name; private double price; public Item(String name, double price) { this.name = name; this.price = price; } public String getName() { return name; } public double getPrice() { return price; } public String toString() { return name + " (" + price + ")"; } }
接着定义一个枚举类型, 用来表示不同的用户级别, 通过该类型将映射到不同的数据源
public enum CustomerType { BRONZE, SILVER, GOLD }
下面是DataSource定义:
<bean id="parentDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" abstract="true"> <property name="driverClassName" value="org.hsqldb.jdbcDriver"/> <property name="username" value="sa"/> </bean> <bean id="goldDataSource" parent="parentDataSource"> <property name="url" value="jdbc:hsqldb:hsql://localhost:${db.port.gold}/blog"/> </bean> <bean id="silverDataSource" parent="parentDataSource"> <property name="url" value="jdbc:hsqldb:hsql://localhost:${db.port.silver}/blog"/> </bean> <bean id="bronzeDataSource" parent="parentDataSource"> <property name="url" value="jdbc:hsqldb:hsql://localhost:${db.port.bronze}/blog"/> </bean> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location" value="classpath:/blog/datasource/db.properties"/> </bean>
AbstractRoutingDataSource 实现类
package blog.datasource; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; public class CustomerRoutingDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return CustomerContextHolder.getCustomerType(); } }
CustomerContextHolder 是一个和LocalThread绑定的类, 定义如下:
public class CustomerContextHolder { private static final ThreadLocal<CustomerType> contextHolder = new ThreadLocal<CustomerType>(); public static void setCustomerType(CustomerType customerType) { Assert.notNull(customerType, "customerType cannot be null"); contextHolder.set(customerType); } public static CustomerType getCustomerType() { return (CustomerType) contextHolder.get(); } public static void clearCustomerType() { contextHolder.remove(); } }
将dao bean和datasource bean结合起来, 至于dao和真正的datasource如何关联这个可以根据需要指定相关的策略和规则来实现:
<bean id="catalog" class="blog.datasource.Catalog"> <property name="dataSource" ref="dataSource"/> </bean> <bean id="dataSource" class="blog.datasource.CustomerRoutingDataSource"> <property name="targetDataSources"> <map key-type="blog.datasource.CustomerType"> <entry key="GOLD" value-ref="goldDataSource"/> <entry key="SILVER" value-ref="silverDataSource"/> </map> </property> <property name="defaultTargetDataSource" ref="bronzeDataSource"/> </bean>
下面通过一个TestCase来看看如何使用:
public class CatalogTests extends AbstractDependencyInjectionSpringContextTests { private Catalog catalog; public void setCatalog(Catalog catalog) { this.catalog = catalog; } public void testDataSourceRouting() { CustomerContextHolder.setCustomerType(CustomerType.GOLD); List<Item> goldItems = catalog.getItems(); assertEquals(3, goldItems.size()); System.out.println("gold items: " + goldItems); CustomerContextHolder.setCustomerType(CustomerType.SILVER); List<Item> silverItems = catalog.getItems(); assertEquals(2, silverItems.size()); System.out.println("silver items: " + silverItems); CustomerContextHolder.clearCustomerType(); List<Item> bronzeItems = catalog.getItems(); assertEquals(1, bronzeItems.size()); System.out.println("bronze items: " + bronzeItems); } protected String[] getConfigLocations() { return new String[] {"/blog/datasource/beans.xml"}; } }
评论
6 楼
liu4187915336
2016-04-26
启动的时候报return (CustomerType) contextHolder.get(); 空指针,get()得到为null,怎么回事
5 楼
fisher
2015-07-07
hbzyb 写道
并发会不会有什么问题呀?
并发应该会有问题,我在找解决办法找了好久。。。。。。。
4 楼
vi19900926
2012-04-22
JTA事务不支持隔离级别吗?
3 楼
pn2008
2012-02-03
如果要在service的一个方法里同时修改多数据源里的数据会出错,数据源并没有转换
2 楼
hbzyb
2011-08-16
并发会不会有什么问题呀?
1 楼
weiqiulai
2010-12-15
如果是不同的数据库如:mysql、mssql,hibernate sessionFactory如何配置呢?是不是只能配置两套了?
发表评论
-
spring中map的定义, 包括value为class的定义
2013-03-11 22:26 37<bean id="fieldM ... -
spring的xml string applicationcontext实现
2013-03-06 07:26 2367这里有两种实现方式: import org.springf ... -
对多数据源进行aop声明式事务管理
2009-11-04 18:57 4987当在对数据库表进行横向切分(将一个表的数据拆分为到多个数据库中 ... -
spring + ibatis 源码解读
2009-10-16 11:46 5707最近对ibatis2.1.0.256这个 ... -
编程方式实现sping bean延迟初始化
2009-10-09 10:12 2761在实际开发中, 碰到如下需求场景: 在线上需要spring容 ... -
使用spring aop 简化mock设计实现
2009-09-28 20:42 2846有时候为了去掉对外部系统的依赖, 我们需要针对外部依赖的接口创 ... -
自定义logger注解, 简化log4j的配置
2009-09-28 20:20 6049上次在参加支付宝架构培训的时候, 看到他们框架中有一个不错的对 ... -
使用spring aop碰到的几个问题及解决办法
2009-09-28 20:09 3946这里的问题只是针对spring 2.0.7 至于其他版本, ... -
本人常用的两种spring aop实现方式
2009-09-28 10:53 3890备忘一下, 基本的用法包括在配置文件中配置pointcut, ... -
spring aspectj的返回值
2009-05-31 08:40 4308最近使用到了基于aspectj的spring aop, aop ... -
spring map bean定义
2009-05-21 12:20 43485一般我们知道在property属性里面定义一个无id的map是 ... -
spring知识总结
2009-05-09 22:11 3256bean属性及构造器参数:直接量(基本类型、Strings类型 ... -
spring @Configration扩展使用一例
2009-02-05 22:03 5799最近对注解了解的比较多, 也在实际项目中实战了一把, 同时对s ... -
spring 注解学习笔记
2009-02-05 21:20 9816spring 注解讲的最详细的文章: http://www.i ... -
spring加载配置文件
2008-12-11 09:27 2354ClassPathXmlApplicationContext ... -
spring aop学习笔记
2008-02-19 14:08 15588理解spring aop的路径:最初级的做法是通过使用代理将业 ...
相关推荐
在"spring-routing-datasource"这个文件中,可能包含了实现Spring动态数据源的示例代码,包括配置文件、路由数据源的实现以及与MyBatis的集成。通过研究这个例子,你可以更深入地理解如何在实际项目中部署和使用这种...
在Spring框架中,动态数据源实现是一个重要的特性,它允许应用程序根据特定的条件或用户需求在运行时切换数据源。这种灵活性对于多租户系统、数据隔离或者在不同环境(如开发、测试、生产)之间切换数据库配置尤其...
这个抽象类维护了一个数据源路由决策表,可以根据特定的规则(如事务上下文、线程局部变量等)来决定使用哪个数据源。开发者需要继承这个类并实现`determineCurrentLookupKey()`方法,该方法返回一个键,该键对应于...
2. **数据源路由**: 在`AbstractRoutingDataSource`中,你需要实现数据源路由的逻辑。例如,你可以基于事务属性、请求上下文或其他自定义条件来决定使用哪个数据源。 3. **配置与注册**: 创建自定义的`...
- `AbstractRoutingDataSource`:这是Spring提供的核心类,用于动态路由数据源。它会根据某种策略(如事务ID、特定的标记等)决定使用哪个数据源。 - `DataSourceTransactionManager`:为每个数据源提供事务管理器...
此外,为了在代码中切换数据源,通常会有一个数据源路由的策略,例如在Service层根据业务逻辑决定使用哪个数据源。这可能涉及到AOP(面向切面编程)的使用,通过注解或配置来切换数据源。 在实际开发中,多数据源的...
本项目“Spring+SpringMVC+Mybatis动态链接多数据源”旨在实现一个灵活、可扩展的数据源切换机制,以适应复杂的业务场景。 Spring框架作为Java领域中最广泛使用的轻量级框架,它提供了强大的依赖注入和AOP(面向切...
通过扩展这个类或直接配置路由规则,我们可以实现数据源的动态选择。 3. **配置多数据源**:在Spring的XML配置文件中,我们需要定义多个DataSource bean,分别代表不同的数据库连接。这些数据源可以是Apache ...
本项目是基于Spring和Mybatis实现的数据路由功能,它允许应用程序在运行时动态地选择合适的数据源,实现了事务级别的控制,并且不需要依赖于特定的配置中心如Spring Cloud。 首先,我们要理解"多数据源"的概念。多...
标题 "mybatis spring 多数据源" 涉及到的...总的来说,"mybatis spring 多数据源"的主题涵盖了如何在Java应用中利用MyBatis和Spring进行多数据库管理,包括数据源配置、动态数据源路由、事务管理以及相关工具的使用。
本主题聚焦于在Spring Cloud环境中实现多数据库和多数据源的整合,并且能够动态切换查询的数据库。这是一个复杂但至关重要的需求,特别是在大型企业级应用中,可能需要根据业务逻辑或用户权限连接到不同的数据库。 ...
这通常通过自定义数据源路由策略实现,例如基于业务标识、负载均衡等方式。在SpringBoot的配置类中,我们可以注册一个Bean,该Bean实现了DataSourceRouter接口,用于实现动态数据源的选择逻辑。 此外,...
总的来说,Spring多数据源分布式事务管理是一项复杂的任务,涉及到Spring的AOP、数据源路由、事务管理等多个方面。通过Atomikos这样的JTA实现,我们可以有效地解决分布式环境下的事务一致性问题。同时,结合Druid和...
本主题将深入探讨如何利用SpringBoot结合Atomikos实现动态多数据源以及事务管理,并介绍两种切换数据源的方法。 首先,SpringBoot简化了传统Spring应用的初始化过程,它通过自动配置和starter包让开发者快速搭建...
- `DynamicDataSourceRouter.java`:实现动态数据源路由,定义选择数据源的规则。 - `Service`和`Repository`层:在业务逻辑中使用动态数据源。 6. **核心代码解析** - `DataSourceConfig`:这里会创建多个`...
2. **配置数据源路由**:Spring的`AbstractRoutingDataSource`可以用来动态选择数据源。我们需要创建一个自定义的类继承`AbstractRoutingDataSource`,并覆盖`determineCurrentLookupKey()`方法来决定当前应该使用...
在Spring Boot应用中,数据源切换是一个常见的需求,特别是在分布式系统...在实际开发中,可以根据业务需求进行调整和优化,比如使用数据库路由策略自动选择数据源,或者利用Spring Cloud Data Flow进行数据源管理。
通过分析这些文件,你可以深入了解如何在Spring Boot中设置和使用多数据源自动路由,包括数据源的配置、路由逻辑的实现、以及如何在代码中透明地使用这些数据源。这个项目是一个很好的学习资源,对于理解和实践...
总结,Spring多数据源动态切换方案主要涉及创建多个数据源、使用AbstractRoutingDataSource进行动态路由、配置事务管理和在代码中切换数据源。通过这种方式,我们可以灵活地处理复杂的数据源切换场景,适应不同业务...
在IT行业中,数据库管理是核心任务之一,而动态数据源技术则是实现多数据库灵活切换的重要手段。本项目涉及的关键技术是"Mybatis-Plus"与"动态数据源"的结合使用,以及一系列相关的配置和扩展。下面将详细阐述这些...