项目是基于Spring的SSM项目,现有一个需求需要对接其他平台查询数据。因为对方平台的数据是存在另一个数据库中所以该项目不仅要连接自己的数据库还要能够连接到对方的数据库。

第一步:编写数据库信息配置文件(用于配置数据库用户名、密码等相关信息)

spring loadUserByUsername 让多个数据源产生乱套 spring怎么配置多个数据源_spring


第二步:编写Spring持久层配置文件:applicationContext-dao.xml

在该配置文件中会配置两个MySQL数据源分别是 :dataSource1和dataSource2。且需要在运行的时候才指定到底使用哪个数据库

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:jpa="http://www.springframework.org/schema/data/jpa"
	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/aop http://www.springframework.org/schema/aop/spring-aop.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
	http://www.springframework.org/schema/data/repository http://www.springframework.org/schema/data/repository/spring-repository.xsd
	http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
	http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">

	<!-- 加载数据库配置文件 -->
	<context:property-placeholder location="classpath:db.properties"/>

	<!-- 数据库连接池 -->
	<bean id="dataSource1" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<property name="url" value="${jdbc.url}" />
		<property name="username" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
		<property name="driverClassName" value="${jdbc.driver}" />
		<property name="initialSize" value="10" />
	    <property name="maxActive" value="50" />
	    <property name="maxIdle" value="15" />
	    <property name="minIdle" value="5" />
	    <property name="removeAbandoned" value="true" />
	    <property name="removeAbandonedTimeout" value="60" />
	    <property name="maxWait" value="10000" />
	    <property name="logAbandoned" value="true" />
	    <property name="testOnBorrow">
	        <value>true</value>
	    </property>
	    <property name="testOnReturn">
	        <value>true</value>
	    </property>
	    <property name="testWhileIdle">
	        <value>true</value>
	    </property>
	    <property name="minEvictableIdleTimeMillis">
	        <value>180000</value>
	    </property>
	    <property name="timeBetweenEvictionRunsMillis">
	        <value>360000</value>
	    </property>
	    <property name="validationQuery">
	        <value>SELECT 1</value>
	    </property>
	</bean>
	<!-- 数据库连接池2 -->
	<bean id="dataSource2" class="org.apache.commons.dbcp.BasicDataSource"
		  destroy-method="close">
		<property name="url" value="${jdbc.url2}" />
		<property name="username" value="${jdbc.username2}" />
		<property name="password" value="${jdbc.password2}" />
		<property name="driverClassName" value="${jdbc.driver2}" />
		<property name="initialSize" value="10" />
		<property name="maxActive" value="50" />
		<property name="maxIdle" value="15" />
		<property name="minIdle" value="5" />
		<property name="removeAbandoned" value="true" />
		<property name="removeAbandonedTimeout" value="60" />
		<property name="maxWait" value="10000" />
		<property name="logAbandoned" value="true" />
		<property name="testOnBorrow">
			<value>true</value>
		</property>
		<property name="testOnReturn">
			<value>true</value>
		</property>
		<property name="testWhileIdle">
			<value>true</value>
		</property>
		<property name="minEvictableIdleTimeMillis">
			<value>180000</value>
		</property>
		<property name="timeBetweenEvictionRunsMillis">
			<value>360000</value>
		</property>
		<property name="validationQuery">
			<value>SELECT 1</value>
		</property>
	</bean>

	<!--配置多个数据源的关键-->
	<bean id="dataSource" class="com.bjxczy.core.common.RoutingDataSource">
		<!-- 为targetDataSources注入两个数据源 -->
		<property name="targetDataSources">
			<map key-type="java.lang.String">
				<entry key="dataSource1" value-ref="dataSource1"/>
				<entry key="dataSource2" value-ref="dataSource2"/>
			</map>
		</property>
		<!-- 为指定数据源RoutingDataSource注入默认的数据源-->
		<property name="defaultTargetDataSource" ref="dataSource1"/>
	</bean>


	<context:component-scan base-package="com.bjxczy">
	   <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
	</context:component-scan>

	<!--Jpa启用扫描并自动创建代理的功能-->
	<jpa:repositories base-package="com.bjxczy.repository" repository-impl-postfix="Impl" entity-manager-factory-ref="entityManagerFactory" transaction-manager-ref="transactionManager" />
    <!-- 实体管理器 -->
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan" value="com.bjxczy.entity" />
        <property name="persistenceProvider">
            <bean class="org.hibernate.ejb.HibernatePersistence" />
        </property>
		<!--hibernate对jpa的实现-->
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="generateDdl" value="false" />
                <property name="database" value="MYSQL" />

				<!--MySQL数据方言-->
				<property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect" />
                <!--神通数据库方言-->
                <!--<property name="databasePlatform" value="org.hibernate.dialect.OscarDialect" />-->

                <!--达梦数据库方言-->

				<!--<property name="databasePlatform" value="org.hibernate.dialect.DmDialect" />-->

                  <!--人大金仓数据库方言-->
                <!--<property name="databasePlatform" value="org.hibernate.dialect.Kingbase8Dialect" />-->

                   <!-- <property name="showSql" value="true" /> -->
            </bean>
        </property>
        <property name="jpaDialect">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
        </property>
		<!-- 指定JPA属性;如Hibernate中指定是否显示SQL的是否显示、方言等 -->
        <property name="jpaPropertyMap">
            <map>
                <entry key="hibernate.query.substitutions" value="true 1, false 0" />
                <entry key="hibernate.default_batch_fetch_size" value="16" />
                <entry key="hibernate.max_fetch_depth" value="2" />
                <entry key="hibernate.generate_statistics" value="true" />
                <entry key="hibernate.bytecode.use_reflection_optimizer" value="true" />
                <entry key="hibernate.cache.use_second_level_cache" value="false" />
                <entry key="hibernate.cache.use_query_cache" value="false" />
            </map>
        </property>
    </bean>

    <!-- jpa事务管理器 -->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>

    <!-- 配置 Annotation 驱动,定义事务  开启注解事务 -->
    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>

	<!-- 配置SqlsessionFactory -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<!-- 加载mybatis的配置文件 -->
		<property name="configLocation" value="classpath:mybatis/SqlMapConfig.xml"/>
		<!-- 配置数据源 -->
		<property name="dataSource" ref="dataSource"/>
	</bean>

	<!--jdbcTemplate使用多个数据源方式 使用时只需要通过注解的方式按照名称拿到该对象即可 -->
	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" abstract="false"
		  lazy-init="false" autowire="default">
		<property name="dataSource">
			<ref bean="dataSource1" />
		</property>
	</bean>
	<bean id="jdbcTemplate2" class="org.springframework.jdbc.core.JdbcTemplate" abstract="false"
		  lazy-init="false" autowire="default">
		<property name="dataSource">
			<ref bean="dataSource2" />
		</property>
	</bean>

	<bean id="myNamedTemplate"
		class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
		<constructor-arg ref="dataSource" />
	</bean>

	<!-- 配置包扫描器,扫描mapper接口生成代理对象放到spring容器中 -->
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<!--  指定要扫描的包  -->
		<property name="basePackage" value="com.bjxczy.mapper"/>
	</bean>

</beans>

其中在配置文件中还定义了一个切换数据库的自定义类:RoutingDataSource

/**
 * @program: AKAuxiliary-1.0
 * @description: 切换数据源
 **/
public class RoutingDataSource extends AbstractRoutingDataSource {

    @Override
    protected Object determineCurrentLookupKey() {

        return DataSourceHolder.getDataSourceType();
    }

}
/**
 * @program: AKAuxiliary-1.0
 * @description: 数据源持有类
 **/
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();
    }

}

配置好数据源后,使用的时候只需要在操作数据库之前(一般在service中) 通过定义的切换数据源类,将需要使用的数据源名称放进去就可以使用该数据源操作数据库了。

spring loadUserByUsername 让多个数据源产生乱套 spring怎么配置多个数据源_数据库_02

另外,刚才看到配置文件中还设置了使用jpa操作数据源并切换数据源,这种情况的使用方式是直接在持久层拿到对应的对象进行操作就可以。

spring loadUserByUsername 让多个数据源产生乱套 spring怎么配置多个数据源_mybatis_03


完结!!!