spring RoutingDataSource使用

在Spring 中引入了AbstractRoutingDataSource, 该类充当了DataSource的路由中介, 能有在运行时, 根据某种key值来动态切换到真正的DataSource上, 同时对于不支持事务隔离级别的JTA事务来说, Spring还提供了另外一个类IsolationLevelDataSourceRouter来处理这个问题. 下面的例子将通过context来切换不同的数据源. 
首先定义一个Catalog的Dao: 



Java代码  

Java代码 
  1.  package blog.datasource;    
  2.     
  3. import java.sql.ResultSet;    
  4. import java.sql.SQLException;    
  5. import java.util.List;    
  6.     
  7. import org.springframework.jdbc.core.simple.ParameterizedRowMapper;    
  8. import org.springframework.jdbc.core.simple.SimpleJdbcDaoSupport;    
  9.     
  10. public class Catalog extends SimpleJdbcDaoSupport {    
  11.             
  12.    public List getItems() {    
  13.       String query = "select name, price from item";    
  14.       return getSimpleJdbcTemplate().query(query, new ParameterizedRowMapper() {    
  15.             public Item mapRow(ResultSet rs, int row) throws SQLException {    
  16.                String name = rs.getString(1);    
  17.                double price = rs.getDouble(2);    
  18.                return new Item(name, price);    
  19.             }    
  20.       });    
  21.    }    
  22. }    




然后定义一个Item的JavaBean 

成都 


Java代码  

Java代码 
  1. package blog.datasource;    
  2.     
  3. public class Item {    
  4.     
  5.    private String name;    
  6.    private double price;    
  7.             
  8.    public Item(String name, double price) {    
  9.       this.name = name;    
  10.       this.price = price;    
  11.    }    
  12.     
  13.    public String getName() {    
  14.       return name;    
  15.    }    
  16.     
  17.    public double getPrice() {    
  18.       return price;    
  19.    }    
  20.     
  21.    public String toString() {    
  22.       return name + " (" + price + ")";    
  23.    }    
  24.     
  25. }    





接着定义一个枚举类型, 用来表示不同的用户级别, 通过该类型将映射到不同的数据源 
CQ

GZ
Java代码  

Java代码 
  1. public enum CustomerType {    
  2.    BRONZE,     
  3.    SILVER,     
  4.    GOLD    
  5. }    



下面是DataSource定义:  HZ 



Xml代码  

Xml代码 
  1. <bean id="parentDataSource"    
  2.          class="org.springframework.jdbc.datasource.DriverManagerDataSource"    
  3.          abstract="true">    
  4.    <property name="driverClassName" value="org.hsqldb.jdbcDriver"/>    
  5.    <property name="username" value="sa"/>    
  6. </bean>    
  7.                     
  8. <bean id="goldDataSource" parent="parentDataSource">    
  9.    <property name="url" value="jdbc:hsqldb:hsql://localhost:${db.port.gold}/blog"/>    
  10. </bean>    
  11.     
  12. <bean id="silverDataSource" parent="parentDataSource">    
  13.    <property name="url" value="jdbc:hsqldb:hsql://localhost:${db.port.silver}/blog"/>    
  14. </bean>    
  15.     
  16. <bean id="bronzeDataSource" parent="parentDataSource">    
  17.    <property name="url" value="jdbc:hsqldb:hsql://localhost:${db.port.bronze}/blog"/>    
  18. </bean>    
  19.     
  20. <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">    
  21.    <property name="location" value="classpath:/blog/datasource/db.properties"/>    
  22. </bean>    



AbstractRoutingDataSource 实现类 



Java代码  

Java代码 
  1. package blog.datasource;    
  2.     
  3. import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;    
  4.     
  5. public class CustomerRoutingDataSource extends AbstractRoutingDataSource {    
  6.     
  7.    @Override    
  8.    protected Object determineCurrentLookupKey() {    
  9.       return CustomerContextHolder.getCustomerType();    
  10.    }    
  11. }    



CustomerContextHolder 是一个和LocalThread绑定的类, 定义如下: 



Java代码  

Java代码 
  1. public class CustomerContextHolder {    
  2.     
  3.    private static final ThreadLocal contextHolder =     
  4.             new ThreadLocal();    
  5.             
  6.    public static void setCustomerType(CustomerType customerType) {    
  7.       Assert.notNull(customerType, &quot;customerType cannot be null&quot;);    
  8.       contextHolder.set(customerType);    
  9.    }    
  10.     
  11.    public static CustomerType getCustomerType() {    
  12.       return (CustomerType) contextHolder.get();    
  13.    }    
  14.     
  15.    public static void clearCustomerType() {    
  16.       contextHolder.remove();    
  17.    }    
  18. }    
  19.   
  20.   
  21.   
  22. 将dao bean和datasource bean结合起来, 至于dao和真正的datasource如何关联这个可以根据需要指定相关的策略和规则来实现:   
  23.   
  24.   
  25.   
  26. Xml代码    
  27. [code=xml]  
  28. <bean id="catalog" class="blog.datasource.Catalog">    
  29.    <property name="dataSource" ref="dataSource"/>    
  30. </bean>    
  31.     
  32. <bean id="dataSource" class="blog.datasource.CustomerRoutingDataSource">    
  33.    <property name="targetDataSources">    
  34.       <map key-type="blog.datasource.CustomerType">    
  35.          <entry key="GOLD" value-ref="goldDataSource"/>    
  36.          <entry key="SILVER" value-ref="silverDataSource"/>    
  37.       </map>    
  38.    </property>    
  39.    <property name="defaultTargetDataSource" ref="bronzeDataSource"/>    
  40. </bean>    



下面通过一个TestCase来看看如何使用: 



Java代码  

Java代码 
  1. public class CatalogTests extends AbstractDependencyInjectionSpringContextTests {    
  2.     
  3.    private Catalog catalog;    
  4.     
  5.    public void setCatalog(Catalog catalog) {    
  6.       this.catalog = catalog;    
  7.    }    
  8.     
  9.    public void testDataSourceRouting() {    
  10.       CustomerContextHolder.setCustomerType(CustomerType.GOLD);    
  11.       List goldItems = catalog.getItems();    
  12.       assertEquals(3, goldItems.size());    
  13.       System.out.println(&quot;gold items: &quot; + goldItems);    
  14.     
  15.       CustomerContextHolder.setCustomerType(CustomerType.SILVER);    
  16.       List silverItems = catalog.getItems();    
  17.       assertEquals(2, silverItems.size());    
  18.       System.out.println(&quot;silver items: &quot; + silverItems);    
  19.             
  20.       CustomerContextHolder.clearCustomerType();    
  21.       List bronzeItems = catalog.getItems();    
  22.       assertEquals(1, bronzeItems.size());    
  23.       System.out.println(&quot;bronze items: &quot; + bronzeItems);                  
  24.    }    
  25.     
  26.    protected String[] getConfigLocations() {    
  27.       return new String[] {&quot;/blog/datasource/beans.xml&quot;};    
  28.    }        
  29. }    




作者:唐山

posted @ 2013-01-09 00:47 chinadiy197601 阅读(...) 评论(...) 编辑 收藏