`
xpz
  • 浏览: 59405 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

spring 动态数据源配置

阅读更多

一、     目的
不同的用户登录到具有表结构相同的各自数据库(一个oracle 服务器),来操作各自的数据,而dao 不知道这些改变。
二、     实现方法
1、分析applicationContext.xml


数据源bean配置

xml 代码
  1. <bean  id="dataSource"  singleton="true"    
  2.            class="org.apache.commons.dbcp.BasicDataSource">    
  3.            <property name="driverClassName">    
  4.                  <value>oracle.jdbc.driver.OracleDrivervalue>    
  5.            property>    
  6.            <property name="url">                 <value>jdbc:oracle:thin:@192.168.0.254:1521:CARRYDLvalue>    
  7.            property>    
  8.            <property name="username">    
  9.                  <value>oavalue>    
  10.            property>    
  11.            <property name="password">    
  12.                  <value>oavalue>    
  13.            property>    
  14.      bean>    
  15. Session 工厂的配置    
  16. <bean id="sessionFactory"           class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">    
  17.             <property name="dataSource">    
  18.                  <ref bean="dataSource" />    
  19.            property>    
  20.            <property name="mappingDirectoryLocations">                 <list><value>classpath:/com/carry/hibernate/value>list>    
  21.            property>    
  22.            <property name="hibernateProperties">    
  23.                  <props>    
  24.                      <prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialectprop>    
  25.                      <!---->    
  26.                      <prop key="hibernate.c3po.min_size">5prop>    
  27.                      <prop key="hibernate.c3po.max_size">20prop>    
  28.                      <prop key="hibernate.c3po.timeout">1800prop>    
  29.                      <!---->    
  30.                      <!---->    
  31.                      <prop key="hibernate.format_sql">trueprop>    
  32.                      <!---->    
  33.                      <!---->    
  34.                      <!---->    
  35.                      <!---->    
  36.                      <!---->    
  37.                      <!---->    
  38.                      <prop key="hibernate.cglib.use_reflection_optimizer">trueprop>    
  39.                  props>    
  40.            property>    
  41.      bean>   

 从上面配置文件可以看出,数据源和session 工厂是一一对应的。
如果配置多个数据源,就要配置多个session工厂,事务的代理就更加的麻烦,所以这样的方法不可取的。所以只能从数据源入手。
2、动态数据源框
由于spring 使用javax.sql.DataSource 统一接口。所以可以复写DataSource具体如下所示:

java 代码
  1. MultiDataSource.java   
  2. package com.carry.spring.datasource;    
  3.   
  4. import java.io.PrintWriter;    
  5. import java.sql.Connection;    
  6. import java.sql.SQLException;    
  7. import java.util.*;    
  8. import javax.sql.DataSource;    
  9. import org.apache.commons.logging.Log;    
  10. import org.apache.commons.logging.LogFactory;    
  11. import org.apache.commons.dbcp.BasicDataSource;    
  12. /    
  13. public class MultiDataSource implements DataSource{    
  14.   
  15.     private static final Log log = LogFactory.getLog(MultiDataSource.class);    
  16.     private static final Map  dataSources =new HashMap();///数据源对象池    
  17.         
  18.     private DataSource dataSource = null;////默认数据源用于测试的数据源    
  19.         
  20.     public Connection getConnection() throws SQLException {    
  21.        return getDataSource().getConnection();    
  22.     }    
  23.   
  24.     public Connection getConnection(String arg0, String arg1)    
  25.            throws SQLException {    
  26.        return getDataSource().getConnection(arg0, arg1);    
  27.     }    
  28.     public PrintWriter getLogWriter() throws SQLException {    
  29.        return getDataSource().getLogWriter();    
  30.     }    
  31.     public int getLoginTimeout() throws SQLException {    
  32.        return getDataSource().getLoginTimeout();    
  33.     }    
  34.     public void setLogWriter(PrintWriter arg0) throws SQLException {    
  35.        getDataSource().setLogWriter(arg0);    
  36.     }    
  37.     public void setLoginTimeout(int arg0) throws SQLException {    
  38.        getDataSource().setLoginTimeout(arg0);    
  39.     }    
  40.         
  41.     public DataSource getDataSource(String dataSourceName)    
  42.     {    
  43.        log.debug("dataSourceName:"+dataSourceName);    
  44.           
  45.               if(dataSourceName==null||dataSourceName.equals(""))    
  46.               {    
  47.                   return this.dataSource;    
  48.               }    
  49.                if(dataSources.get(dataSourceName)!=null)    
  50.                {    
  51.                return (DataSource)dataSources.get(dataSourceName);    
  52.                }    
  53.                else    
  54.                {    
  55.                return  createDataSource(SpObserver.getName(),SpObserver.getPass());    
  56.                }    
  57.                   
  58.           
  59.     }    
  60.         
  61.     public void setDataSource(DataSource dataSource) {    
  62.        this.dataSource = dataSource;    
  63.     }    
  64.   
  65.     public DataSource getDataSource(){    
  66.        String sp = SpObserver.getName();    
  67.        return getDataSource(sp);    
  68.     }    
  69.         
  70.     public DataSource  createDataSource(String userName,String password)    
  71.     {    
  72.        BasicDataSource s =new BasicDataSource();    
  73.        BasicDataSource ts =(BasicDataSource)dataSource;    
  74.        //System.out.println(userName+"____"+password);    
  75.        s.setUsername(userName);    
  76.        s.setPassword(password);    
  77.        s.setUrl(ts.getUrl());    
  78.        s.setDriverClassName(ts.getDriverClassName());    
  79.        dataSources.put(userName, s);    
  80.        return s;    
  81.     }    
  82. }   
共享数据安全为MultiDataSource.java添加如下图所的辅助类
java 代码
  1. SpObserver.java   
  2. package com.carry.spring.datasource;    
  3.   
  4. public class SpObserver {    
  5.     private static ThreadLocal <string></string> localName = new ThreadLocal<string></string>();    
  6.     private static ThreadLocal <string></string>  localPass = new ThreadLocal <string></string> ();    
  7.     public static void putName(String sp)    
  8.     {    
  9.        localName.set(sp);    
  10.     }    
  11.   
  12.     public static String getName()    
  13.     {    
  14.        return (String)localName.get();    
  15.     }    
  16.         
  17.     public static void putPass(String sp)    
  18.     {    
  19.        localPass.set(sp);    
  20.     }    
  21.   
  22.     public static String getPass()    
  23.     {    
  24.        return (String)localPass.get();    
  25.     }    
  26. }   

该类使用ThreadLocal  来存储数据库用户和密码保证数据的不冲突

 

MultiDataSource 需要和MVC 通讯来了解用户需要登录使用那一个数据库,所以必须有一个Filter 来对HttpServletRequest 对象进行监听,来获得登录数据的用户和密码。
如下代码

java 代码
  1. MyFilter.java   
  2. package com.carry.spring.datasource;    
  3. public class MyFilter implements Filter {    
  4.   
  5.     public MyFilter() {    
  6.     }    
  7.   
  8.     public void init(FilterConfig filterConfig) throws ServletException {    
  9.     }    
  10.   
  11.     public void doFilter(ServletRequest request, ServletResponse response,    
  12.            FilterChain chain) throws IOException, ServletException    
  13.     {    
  14.        HttpServletRequest httpRequest = (HttpServletRequest) request;    
  15.        Object nobj=httpRequest.getSession().getAttribute("name");    
  16.        Object pobj=httpRequest.getSession().getAttribute("pass");    
  17.            if(nobj!=null && pobj!=null)    
  18.            {    
  19.               String name = nobj.toString();    
  20.               String pass = pobj.toString();    
  21.               SpObserver.putName(name);    
  22.               SpObserver.putPass(pass);    
  23.               System.out.println("使数据源"+name);    
  24.            }    
  25.            else    
  26.            {    
  27.               SpObserver.putName("");    
  28.               SpObserver.putPass("");    
  29.               System.out.println("用户未登录,使用默认数据源");    
  30.            }    
  31.           
  32.         
  33.        chain.doFilter(request, response);    
  34.     }    
  35.     public void destroy() {    
  36.     }    
  37.   
  38.   
  39. }  
xml 代码
  1. 新的applicationContext.xml 的配置文件如下   
  2.       
  3.   <bean  id="dataSource"  singleton="true"    
  4.            class="org.apache.commons.dbcp.BasicDataSource">    
  5.            <property name="driverClassName">    
  6.                  <value>oracle.jdbc.driver.OracleDrivervalue>    
  7.            property>    
  8.            <property name="url">    
  9.                  <value>jdbc:oracle:thin:@192.168.0.254:1521:CARRYDLvalue>    
  10.            property>    
  11.            <property name="username">    
  12.                  <value>oavalue>    
  13.            property>    
  14.            <property name="password">    
  15.                  <value>oavalue>    
  16.            property>    
  17.      bean>    
  18.         
  19. <!---->    
  20.      <bean  id="multiDataSource" singleton="true"    
  21.             class="com.carry.spring.datasource.MultiDataSource">    
  22.            <property name="dataSource">    
  23.                  <ref bean="dataSource"/>    
  24.            property>    
  25.      bean>    
  26.         
  27.         
  28.      <bean id="sessionFactory"    
  29.            class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">    
  30.             <property name="dataSource">    
  31.                  <ref bean="multiDataSource"/>    
  32.            property>    
  33.            <property name="mappingDirectoryLocations">    
  34.                  <list><value>classpath:/com/carry/hibernate/value>list>    
  35.            property>    
  36.            <property name="hibernateProperties">    
  37.                  <props>    
  38.                      <prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialectprop>    
  39.                      <!---->    
  40.                      <prop key="hibernate.c3po.min_size">5prop>    
  41.                      <prop key="hibernate.c3po.max_size">20prop>    
  42.                      <prop key="hibernate.c3po.timeout">1800prop>    
  43.                      <!---->    
  44.                      <!---->    
  45.                      <prop key="hibernate.format_sql">trueprop>    
  46.                      <!---->    
  47.                      <!---->    
  48.                      <!---->    
  49.                      <!---->    
  50.                      <!---->    
  51.                      <!---->    
  52.                      <prop key="hibernate.cglib.use_reflection_optimizer">trueprop>    
  53.                  props>    
  54.            property>    
  55.            <!---->    
  56.            <property name="lobHandler" ref="lobHandler"/>    
  57.   
  58.      bean>  
  59. 红色为配置文件增加的部分   
  60. Web.xml 的配置增加如下filter   
  61.     <filter>    
  62.        <filter-name>dataSourceFilterfilter-name>    
  63.            <filter-class>    
  64.               com.carry.spring.datasource.MyFilter    
  65.            filter-class>    
  66.     filter>    
  67.     <filter-mapping>    
  68.        <filter-name>dataSourceFilterfilter-name>    
  69.        <url-pattern>/*url-pattern>    
  70. filter-mapping>   
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics