springmvc配置多数据源

有的时候项目中可能要从另外一个系统取数据 如果另外一个系统能提供接口就很好解决 如果没有接口 便可以配置多个数据源切换访问

<1>:这是数据源和事务扫描注入的配置 访问多个数据源只需要建立多个数据源和事务这一套配置文件

这是第一个数据源

<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
    xmlns:context="http://www.springframework.org/schema/context"  
    xmlns:jdbc="http://www.springframework.org/schema/jdbc"   
    xmlns:jee="http://www.springframework.org/schema/jee"  
    xmlns:tx="http://www.springframework.org/schema/tx"   
    xmlns:aop="http://www.springframework.org/schema/aop"  
    xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"  
    xsi:schemaLocation="  
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd  
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd  
        http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd  
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd  
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd  
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd  
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd  
        http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"  
    default-lazy-init="true">  

    <description>Spring公共配置 </description>  

    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  
        <property name="locations">  
            <list>  
                <value>classpath:resources.properties</value>  
                <!--  <value>classpath:memcached.properties</value> -->  
            </list>  
        </property>  
    </bean>  

    <!-- dubbo配置 -->  
    <!-- <dubbo:application name="xaUserRegPro" />  
    <dubbo:registry address="multicast://" />  
    <dubbo:reference id="userRegProService" interface="com.xinnet.xa.service.UserRegProService"  timeout="6000"/> -->  

 <!-- **************** druid 监控连接池配置 ***************** -->  
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">  

        <!-- 基本属性 url、user、password -->  
        <property name="url" value="${url}" />  
        <property name="username" value="${username}" />  
        <property name="password" value="${password}" />  

        <!-- 配置初始化大小、最小、最大 -->  
        <property name="initialSize" value="${initialSize}" />  
        <property name="minIdle" value="${minIdle}" />  
        <property name="maxActive" value="${maxActive}" />  

        <!-- 配置获取连接等待超时的时间 -->  
        <property name="maxWait" value="${maxWait}" />  

        <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->  
        <property name="timeBetweenEvictionRunsMillis" value="60000" />  

        <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->  
        <property name="minEvictableIdleTimeMillis" value="300000" />  
        <property name="validationQuery" value="SELECT 'x'" />  
        <property name="testWhileIdle" value="true" />  
        <property name="testOnBorrow" value="false" />  
        <property name="testOnReturn" value="false" />  

        <!-- 打开PSCache,并且指定每个连接上PSCache的大小  -->  
        <!-- 如果用Oracle,则把poolPreparedStatements配置为true,mysql可以配置为false。分库分表较多的数据库,建议配置为false -->  
        <property name="poolPreparedStatements" value="${poolPreparedStatements}" />  
        <property name="maxPoolPreparedStatementPerConnectionSize" value="20" />  

        <!-- 对泄漏的连接 自动关闭 -->  
        <property name="removeAbandoned" value="${removeAbandoned}" /> <!-- 打开removeAbandoned功能 -->  
        <property name="removeAbandonedTimeout" value="${removeAbandonedTimeout}" /> <!-- 1800秒,也就是30分钟 -->  
        <property name="logAbandoned" value="${logAbandoned}" /> <!-- 关闭abanded连接时输出错误日志 -->  

        <!-- 配置监控统计拦截的filters -->  
        <property name="filters" value="mergeStat" />  
        <!--  <property name="filters" value="stat" /> -->  
        <!-- 慢日志查询  缺省为3秒  修改为1010000 -->  
        <property name="connectionProperties" value="druid.stat.slowSqlMillis=5000" />  

        <!-- DruidDataSource各自独立 , 支持配置公用监控数据 -->  
        <!-- <property name="useGloalDataSourceStat" value="true" /> -->  
    </bean>  

    <!-- druid 监控  spring  -->  
    <bean id="druid-stat-interceptor" class="com.alibaba.druid.support.spring.stat.DruidStatInterceptor"/>  
    <bean id="druid-stat-pointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut" scope="prototype">  
        <property name="patterns">  
            <list>  
                <value>com.xinnet.*.service.*</value>  
            </list>  
        </property>  
    </bean>  
    <aop:config>  
        <aop:advisor advice-ref="druid-stat-interceptor" pointcut-ref="druid-stat-pointcut" />  
    </aop:config>  

    <!-- MyBatis Mapper.XMl 配置 -->  
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">  
        <property name="dataSource" ref="dataSource" />  
        <property name="configLocation" value="classpath:config/mybatis.xml" />  
        <property name="mapperLocations">  
            <list>  
            <!-- 自动匹配Mapper映射文件-->  
                <value>classpath:mapper/****/*-mapper.xml</value>  
            </list>  
        </property>  
        <!-- 添加插件 -->  
        <property name="plugins">  
            <array>  
                <ref bean="pagePlugin" />  
            </array>  
        </property>  
    </bean>  

    <!-- 支持文件上传相关 -->  
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>  

    <!-- 分页插件,根据方言自动添加分页信息,默认要求 -->  
    <bean id="pagePlugin" class="com.xinnet.core.mybatis.plugin.PagePlugin">  
        <property name="properties">  
            <props>  
                <prop key="dialect">com.xinnet.core.mybatis.dialet.MySQLDialect</prop>  
                <prop key="pageSqlId">.*query.*</prop>  
            </props>  
        </property>  
    </bean>  
    <!-- redis客户端 -->  
     <!-- jedis pool配置  -->    
    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">    
        <property name="maxActive" value="${redis.maxActive}" />    
        <property name="maxIdle" value="${redis.maxIdle}" />    
        <property name="maxWait" value="${redis.maxWait}" />    
        <property name="testOnBorrow" value="${redis.testOnBorrow}" />    
    </bean>    

    <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">    
        <property name="usePool" value="true"></property>    
        <property name="hostName" value="${redis.host}" />    
        <property name="port" value="${redis.port}" />    
        <property name="password" value="${redis.pass}" />    
        <property name="timeout" value="${redis.timeout}" />    
        <property name="database" value="${redis.default.db}"></property>    
        <constructor-arg index="0" ref="jedisPoolConfig" />    
    </bean>    
    <bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">    
        <property name="connectionFactory" ref="jedisConnectionFactory" />    
    </bean>  

    <!-- ***************事务配置************** -->  
    <tx:annotation-driven transaction-manager="transactionManager"/>  
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
        <property name="dataSource" ref="dataSource" />  
    </bean>  
    <aop:config>    
             <aop:advisor pointcut="execution(* com.xinnet..service..*.*(..))"  advice-ref="txAdvice" />    
    </aop:config>    
    <tx:advice id="txAdvice" transaction-manager="transactionManager">    
        <tx:attributes>    
            <tx:method name="get*" read-only="true" />    
            <tx:method name="query*" read-only="true" />    
            <tx:method name="find*" read-only="true" />    
            <tx:method name="load*" read-only="true" />  
            <tx:method name="select*" read-only="true" />   
            <tx:method name="count*" read-only="true" />    
            <tx:method name="search*" read-only="true" />    
            <tx:method name="list*" read-only="true" />    
            <tx:method name="*" propagation="REQUIRED" rollback-for="Exception" />    
        </tx:attributes>    
    </tx:advice>    
    <aop:aspectj-autoproxy proxy-target-class="true"/>    
    <!-- 开启注解事务 只对当前配置文件有效 -->  

    <!-- 扫描注解Bean -->  
    <context:component-scan base-package="com.xinnet">  
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>    
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>  
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>  
    </context:component-scan>  
     <!-- 隐式地向 Spring 容器注册 -->  
    <context:annotation-config/>   

</beans>

<2>这是第二个数据源 和第一个数据源一样 需要有事务 扫描注解
不同的是数据源的 url username 和password 用的是第二个数据源的连接 用户名和密码

    <?xml version="1.0" encoding="UTF-8"?>  
    <beans xmlns="http://www.springframework.org/schema/beans"  
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
        xmlns:context="http://www.springframework.org/schema/context"  
        xmlns:jdbc="http://www.springframework.org/schema/jdbc"   
        xmlns:jee="http://www.springframework.org/schema/jee"  
        xmlns:tx="http://www.springframework.org/schema/tx"   
        xmlns:aop="http://www.springframework.org/schema/aop"  
        xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"  
        xsi:schemaLocation="  
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd  
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd  
            http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd  
            http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd  
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd  
            http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd  
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd  
            http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"  
        default-lazy-init="true">  

        <description>Spring公共配置 </description>  

        <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  
            <property name="locations">  
                <list>  
                    <value>classpath:resources.properties</value>  
                    <!--  <value>classpath:memcached.properties</value> -->  
                </list>  
            </property>  
        </bean>  

     <!-- **************** druid 监控连接池配置 *****************  -->  
        <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">  

            <!-- 基本属性 url、user、password -->  
            <property name="url" value="${url2}" />  
            <property name="username" value="${username2}" />  
            <property name="password" value="${password2}" />  

            <!-- 配置初始化大小、最小、最大 -->  
            <property name="initialSize" value="${initialSize}" />  
            <property name="minIdle" value="${minIdle}" />  
            <property name="maxActive" value="${maxActive}" />  

            <!-- 配置获取连接等待超时的时间 -->  
            <property name="maxWait" value="${maxWait}" />  

            <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->  
            <property name="timeBetweenEvictionRunsMillis" value="60000" />  

            <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->  
            <property name="minEvictableIdleTimeMillis" value="300000" />  
            <property name="validationQuery" value="SELECT 'x'" />  
            <property name="testWhileIdle" value="true" />  
            <property name="testOnBorrow" value="false" />  
            <property name="testOnReturn" value="false" />  

            <!-- 打开PSCache,并且指定每个连接上PSCache的大小  -->  
            <!-- 如果用Oracle,则把poolPreparedStatements配置为true,mysql可以配置为false。分库分表较多的数据库,建议配置为false -->  
            <property name="poolPreparedStatements" value="${poolPreparedStatements}" />  
            <property name="maxPoolPreparedStatementPerConnectionSize" value="20" />  

            <!-- 对泄漏的连接 自动关闭 -->  
            <property name="removeAbandoned" value="${removeAbandoned}" /> <!-- 打开removeAbandoned功能 -->  
            <property name="removeAbandonedTimeout" value="${removeAbandonedTimeout}" /> <!-- 1800秒,也就是30分钟 -->  
            <property name="logAbandoned" value="${logAbandoned}" /> <!-- 关闭abanded连接时输出错误日志 -->  

            <!-- 配置监控统计拦截的filters -->  
            <property name="filters" value="mergeStat" />  
            <!--  <property name="filters" value="stat" /> -->  
            <!-- 慢日志查询  缺省为3秒  修改为1010000 -->  
            <property name="connectionProperties" value="druid.stat.slowSqlMillis=5000" />  

            <!-- DruidDataSource各自独立 , 支持配置公用监控数据 -->  
            <!-- <property name="useGloalDataSourceStat" value="true" /> -->  
        </bean>  

        <!-- druid 监控  spring  -->  
        <bean id="druid-stat-interceptor" class="com.alibaba.druid.support.spring.stat.DruidStatInterceptor"/>  
        <bean id="druid-stat-pointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut" scope="prototype">  
            <property name="patterns">  
                <list>  
                    <value>com.xinnet.*.service.*</value>  
                </list>  
            </property>  
        </bean>  
        <aop:config>  
            <aop:advisor advice-ref="druid-stat-interceptor" pointcut-ref="druid-stat-pointcut" />  
        </aop:config>  

        <!-- MyBatis Mapper.XMl 配置 -->  
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">  
            <property name="dataSource" ref="dataSource" />  
            <property name="configLocation" value="classpath:config/mybatis.xml" />  
            <property name="mapperLocations">  
                <list>  
                <!-- 自动匹配Mapper映射文件  -->  
                    <value>classpath:mapper/****/*-mapper.xml</value>  
                </list>  
            </property>  
            <!-- 添加插件 -->  
            <property name="plugins">  
                <array>  
                    <ref bean="pagePlugin" />  
                </array>  
            </property>  
        </bean>  

        <!-- 支持文件上传相关 -->  
        <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>  

        <!-- 分页插件,根据方言自动添加分页信息,默认要求 -->  
        <bean id="pagePlugin" class="com.xinnet.core.mybatis.plugin.PagePlugin">  
            <property name="properties">  
                <props>  
                    <prop key="dialect">com.xinnet.core.mybatis.dialet.MySQLDialect</prop>  
                    <prop key="pageSqlId">.*query.*</prop>  
                </props>  
            </property>  
        </bean>  
        <!-- redis客户端 -->  
         <!-- jedis pool配置  -->    
        <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">    
            <property name="maxActive" value="${redis.maxActive}" />    
            <property name="maxIdle" value="${redis.maxIdle}" />    
            <property name="maxWait" value="${redis.maxWait}" />    
            <property name="testOnBorrow" value="${redis.testOnBorrow}" />    
        </bean>    

        <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">    
            <property name="usePool" value="true"></property>    
            <property name="hostName" value="${redis.host}" />    
            <property name="port" value="${redis.port}" />    
            <property name="password" value="${redis.pass}" />    
            <property name="timeout" value="${redis.timeout}" />    
            <property name="database" value="${redis.default.db}"></property>    
            <constructor-arg index="0" ref="jedisPoolConfig" />    
        </bean>    
        <bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">    
            <property name="connectionFactory" ref="jedisConnectionFactory" />    
        </bean>  

        <!-- ***************事务配置************** -->  
        <tx:annotation-driven transaction-manager="transactionManager"/>  
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
            <property name="dataSource" ref="dataSource" />  
        </bean>  
        <aop:config>    
                 <aop:advisor pointcut="execution(* com.xinnet..service..*.*(..))"  advice-ref="txAdvice" />    
        </aop:config>    
        <tx:advice id="txAdvice" transaction-manager="transactionManager">    
            <tx:attributes>    
                <tx:method name="get*" read-only="true" />    
                <tx:method name="query*" read-only="true" />    
                <tx:method name="find*" read-only="true" />    
                <tx:method name="load*" read-only="true" />  
                <tx:method name="select*" read-only="true" />   
                <tx:method name="count*" read-only="true" />    
                <tx:method name="search*" read-only="true" />    
                <tx:method name="list*" read-only="true" />    
                <tx:method name="*" propagation="REQUIRED" rollback-for="Exception" />    
            </tx:attributes>    
        </tx:advice>    
        <aop:aspectj-autoproxy proxy-target-class="true"/>    
        <!-- 开启注解事务 只对当前配置文件有效 -->  

        <!-- 扫描注解Bean -->  
        <context:component-scan base-package="com.xinnet">  
            <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>    
            <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>  
            <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>  
        </context:component-scan>  
         <!-- 隐式地向 Spring 容器注册 -->  
        <context:annotation-config/>   

    </beans>  

<3>这个时候就可以用两个数据源进行切换注入 从而使用不同数据源的service

这是service里面的方法 该怎么写就是怎么写 该怎么注解就怎么注解 不用做特殊的步骤

[java] view plain copy
在CODE上查看代码片派生到我的代码片

@Service("partyService")  
public class PartyServiceImpl implements PartyService {  

    @Autowired  
    private PartyDao partyDao;  

    @Override  
    public List<Emp> getAllEmp() throws SQLException {  
        return partyDao.getAllEmp();  
    }  

}  

Dao层也是一样 该怎么写就怎么写 该怎么注解就怎么注解

然后可以写一个测试类试一下连接

[java] view plain copy
在CODE上查看代码片派生到我的代码片

@RunWith(SpringJUnit4ClassRunner.class)  
@ContextConfiguration(locations = { "classpath:spring.xml" })//这里的spring.xml加载了第一个数据源 spring-commons.xml   
public class DataSourceTest extends AbstractTransactionalJUnit4SpringContextTests {  
    /** 
     *  
     * 功能描述:xxxxx 
     * 
     * @throws SQLException 
     * 
     * @author xxx[973893384@163.com] 
     * 
     * @since 2014年3月12日 
     * 
     * @update:[变更日期YYYY-MM-DD][更改人姓名][变更描述] 
     */  
    @Test  
    @Rollback(true)  
    public void testGetAllEmp() throws SQLException {  
        ApplicationContext ac = new FileSystemXmlApplicationContext("classpath:config/hymanager/hymanager_spring.xml");//这里加载的是第二个数据源配置文件路径 使用的时候用application 读取第二个数据源的配置文件 就可以用getBean 获取注入的service 不用ac.getBean 用@Autowired自动注入的 则使用的是第一个数据源    
        PartyService partyService = (PartyService) ac.getBean("partyService");  
        List<Emp> list = partyService.getAllEmp();  
        for (Emp emp : list) {  
            System.out.println(emp.getEmpno());  
        }  
    }  

这样就可以封装一个父类

[java] view plain copy
在CODE上查看代码片派生到我的代码片

public class DataSourceChange {  
    //第二个数据源数据源  
    public ApplicationContext otherDataSource=new FileSystemXmlApplicationContext("classpath:config/hymanager/hymanager_spring.xml");  
    //默认数据源  
    public ApplicationContext defaultDataSource=new FileSystemXmlApplicationContext("classpath:config/spring_commons.xml");  
    /** 
     *  
     * 功能描述:xxxx 
     * 
     * @param beanName 
     * @return 
     * 
     * @author xxx[973893384@163.com] 
     * 
     * @since 2014年3月12日 
     * 
     * @update:[变更日期YYYY-MM-DD][更改人姓名][变更描述] 
     */  
    public Object now(String beanName) {  
        return defaultDataSource.getBean(beanName);  
    }  
    public Object after(String beanName) {  
        return otherDataSource.getBean(beanName);  
    }  
}  

要使用多个数据源的类就可以继承这个父类

    public class HyMangerEmpDataHandle extends DataSourceChange {  
        //用父类的after方法更换配置切换第二套数据源获取注入partyService  
        private PartyService partyService=(PartyService) after("partyService");  

        //<span style="font-family: Arial, Helvetica, sans-serif;">用父类的now方法</span>更换配置切换第一套数据源获取注入empService  
        private EmpService empService=(EmpService) now("empService");  

        private static Logger log=LoggerFactory.getLogger(PartyService.class);  
        /** 
         *  
         * 功能描述:xxxxx 
         * 
         * @throws SQLException 
         * 
         * @author xxx[973893384@163.com] 
         * 
         * @since 2014年3月12日 
         * 
         * @update:[变更日期YYYY-MM-DD][更改人姓名][变更描述] 
         */  
        public void leadingAllEmp() throws SQLException {  
            List<Emp> partyList=partyService.getAllEmp();//第二个数据源注入的service  
            for(Emp emp:partyList) {  
                empService.addEmp(emp);//第一个数据源注入的service  
            }  
        }  
    }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值