SSM配置多数据源并可动态切换操作

接到的需求是对本地数据库进行什么操作,就也要对服务器上的数据库进行同样的操作,本地是MySQL,服务器上是SQL server,公司服务器这两天没弄好,所以就先在本地对MySQL和SQL server进行测试。在组长刚告诉我这个需求的时候我觉得应该不算难,在把项目基本架构搭好调试好之后就开始着手做这个功能,但是仔细一想自己的思路是错的,从三层架构上来说应该是实现不了。于是就开始了面向百度编程的操作,在看了很多大同小异的技术博客以及让我的大佬同学帮我调试之后,于昨晚凌晨两点半终于可以正常使用了,但是只是一个Demo。在这里做一下笔记,以便以后复习。

项目结构

https://img-blog.csdnimg.cn/20191230094505840.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L29ha19qYXZhTGVhcm5lcg==,size_16,color_FFFFFF,t_70
java文件夹下的就不写了,测试代码而已,下面是对工具类以及配置文件中相对于只能跑通的时候所添加的东西的描述:

1.DataSourceHolder : 这是一个数据源持有类,可以定义get/set方法去查看/设置当前数据源,而且ThreadLocal也可以对两个数据源在多线程操作的时候提供线程保护,以便清楚的实现业务逻辑。

package com.tdhc.utils;


/**
 * 数据源持有类
 * @author yule
 * @date 2018/9/28 19:34
 */
public class DataSourceHolder {
    private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();

    /**
     * @Description: 设置数据源类型
     * @param dataSourceType  数据库类型
     * @return void
     * @throws
     */
    public static void setDataSourceType(String dataSourceType) {
        contextHolder.set(dataSourceType);
    }

    /**
     * @Description: 获取数据源类型
     * @return String
     * @throws
     */
    public static String getDataSourceType() {
        return contextHolder.get();
    }

    /**
     * @Description: 清除数据源类型
     * @return void
     * @throws
     */
    public static void clearDataSourceType() {
        contextHolder.remove();
    }

}

2.RoutingDataSource : 这个是一个路由类,具体怎么实现的我也还没搞明白,不过在做的时候看到很多博客上都写了这个类,应该是对不同的数据源进行操作的时候有一个对不同数据库的分发操作机制吧。

package com.tdhc.utils;

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

/**
 * 路由类
 * @author yule
 * @date 2018/9/28 19:29
 */
public class RoutingDataSource extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        return DataSourceHolder.getDataSourceType();
    }
}

3.在jdbc.properties中配置两个数据源:(我配的是一个MySQL一个SQL server)

#============================#
#==== Database settings ====#
#============================#

# JDBC
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.connectionURL=jdbc:mysql://localhost:3306/tdhc_quality?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
jdbc.username=root
jdbc.password=1234

jdbc.servet.driverClass=com.microsoft.sqlserver.jdbc.SQLServerDriver
jdbc.servet.connectionURL=jdbc:sqlserver://localhost:2325;databaseName=AAA
jdbc.servet.username=sa
jdbc.servet.password=123456

# JDBC Pool
jdbc.pool.init=1
jdbc.pool.minIdle=3
jdbc.pool.maxActive=20



#============================#
#==== Framework settings ====#
#============================#

# \u89c6\u56fe\u6587\u4ef6\u5b58\u653e\u8def\u5f84
web.view.prefix=/WEB-INF/views/
web.view.suffix=.jsp

web.maxUploadSize=10485760

4.spring-context-druid.xml : 在这个文件里配置了对两个数据源的连接信息取值,以及连接数据库时的一些配置,并且要给两个数据源命名,然后在配置数据源路由的时候用这两个名字对两个数据源进行引用。

<?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:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- 加载配置属性文件 -->
    <context:property-placeholder ignore-unresolvable="true" location="classpath:jdbc_MySQL.properties"/>

    <!--配置数据源路由-->
    <bean id="dataSource" class="com.tdhc.utils.RoutingDataSource">
        <!-- 为targetDataSources注入两个数据源 -->
        <property name="targetDataSources">
            <map key-type="java.lang.String">
                <entry key="db1" value-ref="firstDataSource"/>
                <entry key="db2" value-ref="secondDataSource"/>
            </map>
        </property>
        <!-- 为指定数据源RoutingDataSource注入默认的数据源-->
        <property name="defaultTargetDataSource" ref="firstDataSource"/>
    </bean>




    <!-- 需要 commons.dbcp 包 -->
    <bean id="firstDataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClass}"/>
        <property name="url" value="${jdbc.connectionURL}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
        <property name="maxIdle" value="20"/>
        <property name="defaultAutoCommit" value="true"/>
        <property name="removeAbandonedTimeout" value="60"/>
        <property name="testOnBorrow" value="true"/>
        <property name="testOnReturn" value="true"/>
        <property name="testWhileIdle" value="true"/>
    </bean>

    <!--数据源二-->
    <bean id="secondDataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.servet.driverClass}"/>
        <property name="url" value="${jdbc.servet.connectionURL}"/>
        <property name="username" value="${jdbc.servet.username}"/>
        <property name="password" value="${jdbc.servet.password}"/>
        <property name="maxIdle" value="20"/>
        <property name="defaultAutoCommit" value="true"/>
        <property name="removeAbandonedTimeout" value="60"/>
        <property name="testOnBorrow" value="true"/>
        <property name="testOnReturn" value="true"/>
        <property name="testWhileIdle" value="true"/>
    </bean>


</beans>

5.spring-context-mybatis.xml : 在这个文件里面配置了sqlsessionFactory,对双数据源操作主要就是以创建两个connect实现的,所以sqlsessionFactory一定要配置好,里面包含了对实体类的扫描以及mapper文件的位置和有关创建sqlsessionFactory的配置文件的位置,还有就是mapper.xml文件的位置扫描需要另外配置。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- 配置 SqlSession -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!-- 用于配置对应实体类所在的包,多个 package 之间可以用 ',' 号分割 -->
        <property name="typeAliasesPackage" value="com.tdhc.domain"/>
        <!-- 用于配置对象关系映射配置文件所在目录 -->
        <property name="mapperLocations" value="classpath*:/mapper/**/*.xml"/>
        <property name="configLocation" value="classpath:/mybatis-config.xml"/>
    </bean>

    <!-- 扫描 Mapper -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.tdhc.mapper" />
    </bean>
</beans>

6.spring-mvc.xml : 这个文件没有改动,因为这个文件并没有关于数据源操作的配置,主要是对bean的实例化,以及资源映射器,视图解析器,还有编码过滤器等的配置,这里放出来做个记录吧。

<?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:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <description>Spring MVC Configuration</description>

    <!-- 加载配置属性文件  xml配置文件中需要的属性参数都可以放在其中 -->
    <context:property-placeholder ignore-unresolvable="true" location="classpath:*.properties"/>

    <!-- 使用 Annotation 自动注册 Bean,只扫描 @Controller 从base-package下开始扫描, 如果controller写到其他地方 需要另配。 -->
    <context:component-scan base-package="com.tdhc.controller" use-default-filters="false">
        <!-- 这里只能扫描到Controller  -->
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <!-- 定义视图文件解析 -->
    <!-- controller 返回 index.jsp 之类的时候要用。 告诉文件的具体位置 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="${web.view.prefix}"/>
        <property name="suffix" value="${web.view.suffix}"/>
    </bean>

    <!-- 静态资源映射 -->
    <mvc:resources mapping="/static/**" location="/static/" cache-period="31536000"/>

    <!-- 处理请求返回json字符串的中文乱码问题 -->
    <mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>application/json;charset=UTF-8</value>
                    </list>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>
</beans>

总结一下:
1.对多数据源的配置要在jdbc.properties中配置两个数据库的连接信息
2.在其他配置文件中对数据源驱动包配置的时候进行读取,并且命名,并配置数据库路由,通过命名对其引用,并设置默认数据源。
3.在别的配置文件中有对这些配置的引用的话一定要保持一致
4.要注意的问题是数据源驱动包与tomcat版本的问题,另外就是项目依赖要规范,防止出现依赖冲突。

如果有不对的地方欢迎评论指正,感谢。

发布了15 篇原创文章 · 获赞 2 · 访问量 814

猜你喜欢

转载自blog.csdn.net/oak_javaLearner/article/details/103761325
今日推荐