一、 目的
不同的用户登录到具有表结构相同的各自数据库(一个oracle 服务器),来操作各自的数据,而dao 不知道这些改变。
二、 实现方法
1、分析applicationContext.xml
数据源bean配置
xml 代码
- <bean id="dataSource" singleton="true"
- class="org.apache.commons.dbcp.BasicDataSource">
- <property name="driverClassName">
- <value>oracle.jdbc.driver.OracleDrivervalue>
- property>
- <property name="url"> <value>jdbc:oracle:thin:@192.168.0.254:1521:CARRYDLvalue>
- property>
- <property name="username">
- <value>oavalue>
- property>
- <property name="password">
- <value>oavalue>
- property>
- bean>
- Session 工厂的配置
- <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
- <property name="dataSource">
- <ref bean="dataSource" />
- property>
- <property name="mappingDirectoryLocations"> <list><value>classpath:/com/carry/hibernate/value>list>
- property>
- <property name="hibernateProperties">
- <props>
- <prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialectprop>
-
- <prop key="hibernate.c3po.min_size">5prop>
- <prop key="hibernate.c3po.max_size">20prop>
- <prop key="hibernate.c3po.timeout">1800prop>
-
-
- <prop key="hibernate.format_sql">trueprop>
-
-
-
-
-
-
- <prop key="hibernate.cglib.use_reflection_optimizer">trueprop>
- props>
- property>
- bean>
从上面配置文件可以看出,数据源和session 工厂是一一对应的。
如果配置多个数据源,就要配置多个session工厂,事务的代理就更加的麻烦,所以这样的方法不可取的。所以只能从数据源入手。
2、动态数据源框
由于spring 使用javax.sql.DataSource 统一接口。所以可以复写DataSource具体如下所示:
java 代码
- MultiDataSource.java
- package com.carry.spring.datasource;
-
- import java.io.PrintWriter;
- import java.sql.Connection;
- import java.sql.SQLException;
- import java.util.*;
- import javax.sql.DataSource;
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
- import org.apache.commons.dbcp.BasicDataSource;
- /
- public class MultiDataSource implements DataSource{
-
- private static final Log log = LogFactory.getLog(MultiDataSource.class);
- private static final Map dataSources =new HashMap();
-
- private DataSource dataSource = null;
-
- public Connection getConnection() throws SQLException {
- return getDataSource().getConnection();
- }
-
- public Connection getConnection(String arg0, String arg1)
- throws SQLException {
- return getDataSource().getConnection(arg0, arg1);
- }
- public PrintWriter getLogWriter() throws SQLException {
- return getDataSource().getLogWriter();
- }
- public int getLoginTimeout() throws SQLException {
- return getDataSource().getLoginTimeout();
- }
- public void setLogWriter(PrintWriter arg0) throws SQLException {
- getDataSource().setLogWriter(arg0);
- }
- public void setLoginTimeout(int arg0) throws SQLException {
- getDataSource().setLoginTimeout(arg0);
- }
-
- public DataSource getDataSource(String dataSourceName)
- {
- log.debug("dataSourceName:"+dataSourceName);
-
- if(dataSourceName==null||dataSourceName.equals(""))
- {
- return this.dataSource;
- }
- if(dataSources.get(dataSourceName)!=null)
- {
- return (DataSource)dataSources.get(dataSourceName);
- }
- else
- {
- return createDataSource(SpObserver.getName(),SpObserver.getPass());
- }
-
-
- }
-
- public void setDataSource(DataSource dataSource) {
- this.dataSource = dataSource;
- }
-
- public DataSource getDataSource(){
- String sp = SpObserver.getName();
- return getDataSource(sp);
- }
-
- public DataSource createDataSource(String userName,String password)
- {
- BasicDataSource s =new BasicDataSource();
- BasicDataSource ts =(BasicDataSource)dataSource;
-
- s.setUsername(userName);
- s.setPassword(password);
- s.setUrl(ts.getUrl());
- s.setDriverClassName(ts.getDriverClassName());
- dataSources.put(userName, s);
- return s;
- }
- }
共享数据安全为MultiDataSource.java添加如下图所的辅助类
java 代码
- SpObserver.java
- package com.carry.spring.datasource;
-
- public class SpObserver {
- private static ThreadLocal <string></string> localName = new ThreadLocal<string></string>();
- private static ThreadLocal <string></string> localPass = new ThreadLocal <string></string> ();
- public static void putName(String sp)
- {
- localName.set(sp);
- }
-
- public static String getName()
- {
- return (String)localName.get();
- }
-
- public static void putPass(String sp)
- {
- localPass.set(sp);
- }
-
- public static String getPass()
- {
- return (String)localPass.get();
- }
- }
该类使用ThreadLocal 来存储数据库用户和密码保证数据的不冲突
MultiDataSource 需要和MVC 通讯来了解用户需要登录使用那一个数据库,所以必须有一个Filter 来对HttpServletRequest 对象进行监听,来获得登录数据的用户和密码。
如下代码
java 代码
- MyFilter.java
- package com.carry.spring.datasource;
- public class MyFilter implements Filter {
-
- public MyFilter() {
- }
-
- public void init(FilterConfig filterConfig) throws ServletException {
- }
-
- public void doFilter(ServletRequest request, ServletResponse response,
- FilterChain chain) throws IOException, ServletException
- {
- HttpServletRequest httpRequest = (HttpServletRequest) request;
- Object nobj=httpRequest.getSession().getAttribute("name");
- Object pobj=httpRequest.getSession().getAttribute("pass");
- if(nobj!=null && pobj!=null)
- {
- String name = nobj.toString();
- String pass = pobj.toString();
- SpObserver.putName(name);
- SpObserver.putPass(pass);
- System.out.println("使数据源"+name);
- }
- else
- {
- SpObserver.putName("");
- SpObserver.putPass("");
- System.out.println("用户未登录,使用默认数据源");
- }
-
-
- chain.doFilter(request, response);
- }
- public void destroy() {
- }
-
-
- }
xml 代码
- 新的applicationContext.xml 的配置文件如下
-
- <bean id="dataSource" singleton="true"
- class="org.apache.commons.dbcp.BasicDataSource">
- <property name="driverClassName">
- <value>oracle.jdbc.driver.OracleDrivervalue>
- property>
- <property name="url">
- <value>jdbc:oracle:thin:@192.168.0.254:1521:CARRYDLvalue>
- property>
- <property name="username">
- <value>oavalue>
- property>
- <property name="password">
- <value>oavalue>
- property>
- bean>
-
-
- <bean id="multiDataSource" singleton="true"
- class="com.carry.spring.datasource.MultiDataSource">
- <property name="dataSource">
- <ref bean="dataSource"/>
- property>
- bean>
-
-
- <bean id="sessionFactory"
- class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
- <property name="dataSource">
- <ref bean="multiDataSource"/>
- property>
- <property name="mappingDirectoryLocations">
- <list><value>classpath:/com/carry/hibernate/value>list>
- property>
- <property name="hibernateProperties">
- <props>
- <prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialectprop>
-
- <prop key="hibernate.c3po.min_size">5prop>
- <prop key="hibernate.c3po.max_size">20prop>
- <prop key="hibernate.c3po.timeout">1800prop>
-
-
- <prop key="hibernate.format_sql">trueprop>
-
-
-
-
-
-
- <prop key="hibernate.cglib.use_reflection_optimizer">trueprop>
- props>
- property>
-
- <property name="lobHandler" ref="lobHandler"/>
-
- bean>
- 红色为配置文件增加的部分
- Web.xml 的配置增加如下filter
- <filter>
- <filter-name>dataSourceFilterfilter-name>
- <filter-class>
- com.carry.spring.datasource.MyFilter
- filter-class>
- filter>
- <filter-mapping>
- <filter-name>dataSourceFilterfilter-name>
- <url-pattern>/*url-pattern>
- filter-mapping>
分享到:
相关推荐
spring数据源配置
spring 动态多数据源配置代码,本项目是maven项目,里面有完成的配资好的spring多数据源代码和配置文件。
spring动态数据源整合mybatis实现的分库分表操作。 分库分表对业务代码是透明的,只需要在配置文件分配分库模版即可动态的实现分库分表的增删改查操作。
Spring多数据源配置,支持mysql、oracle等多个数据源同时存在的情况
阐述spring的数据源配置
Spring多数据源配置_分布式数据 Tomcat服务器下的多数据源配置详情 一、环境及框架 Tomcat+spring+hibernate+jotm,还有就是struts、Oracle等 二、需求说明 系统里有2套不同网域的oracle数据库,之间的数据需要进行...
基于注解的Spring多数据源配置和使用 前一段时间研究了一下spring多数据源的配置和使用,为了后期从多个数据源拉取数据定时进行数据分析和报表统计做准备。由于之前做过的项目都是单数据源的,没有遇到这种场景,...
一个springboot的多数据配置,从mapper到controller完整的一个业务流程
使用注解配置实现Spring动态数据源切换,实现原理 1、自定义动态数据源类DynamicDataSource: 实现spring类AbstractRoutingDataSource的方法determineCurrentLookupKey 2、自定义Spring AOP类DataSourceAspect 3、...
通过简单的demo实现SpingBoot多数据源配置并动态切换多数据源
spring配置JNDI数据源
springboot多数据源配置
请自行修改com/resources/datasource.properties中数据库配置,Demo中配置的两个数据源,一个是Mysql,一个是Oracle。 运行之前请自行建立数据库的表。
Spring Boot使用spring-data-jpa配置Mysql多数据源,可用版本
mybatis+spring实现动态切换数据源,修改数据源配置信息之后,直接运行test可进行测试
SSM(Spring+SpringMVC+MyBatis)多数据源配置框架,精简版
IOC容器数据源配置 <!-- 配置数据源 --> destroy-method="close"> <value>org.gjt.mm.mysql.Driver <value>jdbc:mysql://localhost:3306/demo <value>root <value>root ...
NULL 博文链接:https://cuics-100.iteye.com/blog/662102
spring 配置多数据源