1. 程式人生 > >wordybear之STS下spring boot、mybatis多資料來源配置完全攻略及原始碼工程

wordybear之STS下spring boot、mybatis多資料來源配置完全攻略及原始碼工程

// 2017.09.01 本文所依賴的開發環境早已更改為intellij idea,然而並不影響任何

本文面對初學者,在對基礎有些瞭解但又似懂非懂有些混亂的情況下(作者一般學習新技的最初狀態,此時需要冷靜)。

但是,仔細閱讀本文,將會在相同或相似的環境下實現sts下spring boot、mybatis多資料來源的配置。多資料來源,在專案中,真的常用。

本文給出最終實現細節的同時,另一個目的是對最近幾天的學習探索進行流水式記錄,很多踩到的坑兒,你或許也會經歷,請耐心。

注:雖然已經可以搜到大量的指明完成本文工作的文章,但測試後要麼感覺新手無法勝任、要麼無法實現、要麼不完整,本文力求從無到有(除了建立mysql、sql server2005資料庫)。

1、背景

spring、mybatis的按部就班操作已經不少時日了,然而內心一直想做一套從架構上感覺很爽的方案,正好最近的一個專案讓我覺得有必要仔細規劃一下。

在以前的專案開發上,由於硬體配置受限、既有方案等,一直使用的開發環境版本很落後,這次趁自己升級了電腦配置,將要做的專案也算從0配置,因此最終選定了使用當前版本的sts(3.8.4.RELEASE)下spring boot的方式。

由於一直認為業務性的系統框架與具體的開發環境、語言等通常弱相關,因此當前的重點是測試性的完成系統實現需要的某些技術細節的準備,本文是為了解決專案中經常需要的多資料來源訪問配置問題。

2、環境

Spring ToolSuite(STS):

3.8.4.RELEASE;

64位版本;

jdk:

    jdk-7u75-windows-x64

maven:

    apache-maven-3.3.1-bin(未使用sts自帶)

其他元件:

    Druid、sqljdbc4、mysql(這些都可通過pom進行配置)

注意:開發spring boot時,一定要聯網(見《springboot實戰》的說明)

3、spring與mybatis的配置

由於對spring boot的一片茫然,在最開始折騰時,混亂中也忘記了spring boot本來也僅是多加了一層功能用於簡化配置,在它之中整合mybatis其實也是對原先spring+mybatis的mybatis.xml檔案進行xml配置註解化,這本來是一個有效突破口的(可惜最初根本沒思考),即註解最終必須等價於過去xml配置的效果才算是有效完成。無論對單一資料來源,還是多個數據源,這個突破口都應該適用。外加一句,僅使用spring+jdbc,想要註解化,上面的原則也適用。

mybatis.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:aop="http://www.springframework.org/schema/aop"
	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/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">

	<!-- 配置dataSource -->
	<bean id="dataSource_sql2v5_testdb" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
		<property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" />
		<property name="url"
			value="jdbc:sqlserver://127.0.0.1:1433;databaseName=testdb;integratedSecurity=false" />
		<property name="username" value="sa" />
		<property name="password" value="mspassword" />
		<!-- 初始化連線大小 -->
		<property name="initialSize" value="5"></property>
		<!-- 連線池最大數量 -->
		<property name="maxActive" value="20"></property>
		<!-- 連線池最大空閒 -->
		<property name="maxIdle" value="5"></property>
		<!-- 連線池最小空閒 -->
		<property name="minIdle" value="5"></property>
		<!-- 獲取連線最大等待時間 -->
		<property name="maxWait" value="60000"></property>
	</bean>
	<!-- 配置sessionfactory -->
	<bean id="sqlSessionFactory_sql2v5_testdb" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource_sql2v5_testdb" />
		<!-- 自動掃描mapping.xml檔案 -->
		<property name="mapperLocations" value="classpath*:/**/testdb/mapper/*.xml"></property>
	</bean>
	<bean id="sqlSessionTemplate_sql2v5_testdb" class="org.mybatis.spring.SqlSessionTemplate">   
          <constructor-arg index="0" ref="sqlSessionFactory" />   
    </bean>  
	<!-- 裝配dao介面 -->
	<bean id="mapperScanner_sql2v5_testdb" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="com.zcn.swc.domain.testdb.mapper.testdb.dbo" />
		<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory_sql2v5_testdb"></property>
	</bean>
	<!-- 宣告式事務管理 -->
	<bean id="transactionManager_sql2v5_testdb" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource_sql2v5_testdb" />
	</bean>  
</beans>

在spring自動掃描時,依據上面的xml配置與mybatis進行整合。

4、spring boot中註解實現應該做的事情

按照spring與mybatis的xml配置順序,在使用註解時,對單一資料來源配置,需要按照以下順序進行:

一、讀取資料來源引數配置;

二、使用資料來源引數建立一個數據源dataSource(本文使用DruidDataSource) bean;

三、由dataSource bean建立一個sqlSessionFactorybean;

四、由sqlSessionFactory bean建立一個sqlSessionTemplatebean;

五、由sqlSessionFactory、sqlSessionTemplate建立MapperScannerConfigurer bean;(此步非常重要,必須建立在三、四的基礎之上);

六、事務管理bean,基於第一步的dataSource bean建立。

對多資料來源,在spring boot中使用mybatis,與單一資料來源具有不同的特點,重要的幾點:

一、若不同資料來源配置檔案採用不同的.properties檔案(所有配置檔案內的屬性都相同,僅屬性值不同),則你可能無法使用org.springframework.beans.factory.config.PropertyPlaceholderConfigurer類進行配置,因為每個配置檔案裡的屬性都相同,從直觀上來看,至少後來者會覆蓋先前的屬性值,你可能也無法使用Environment類(我沒有深入,也可能是我的用法不對),與PropertyPlaceholderConfigurer的問題類似。

你需要在某個mybatis註解配置類中,使用java.util.Properties類,手動的去載入配置檔案,目前我覺得這也是一種不錯的方案,至少可以保障所有的配置檔案屬性統一,示例如下:

jdbc.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
jdbc.url=jdbc:sqlserver://127.0.0.1:1433;databaseName=testdb02;integratedSecurity=false
jdbc.username=sa
jdbc.password=password

jdbc.initialSize=5
jdbc.minIdle=5
jdbc.maxActive=20
jdbc.maxWait=60000
jdbc.timeBetweenEvictionRunsMillis=60000
jdbc.minEvictableIdleTimeMillis=300000
jdbc.poolPreparedStatements=true
jdbc.maxPoolPreparedStatementPerConnectionSize=20

jdbc.filters=stat,wall

#mybatis
mybatis.configLocation=classpath:/mb/mb-cfg-sql2v5-testdb02.xml
mybatis.typeAliasesPackage=com.zcn.swc.domain.testdb02.model
mybatis.mapperLocations=classpath*:/**/testdb02/mapper/*.xml

我的配置不是想做成下面這種形式:

#dataSourceAAA.properties檔案內屬性

spring.mysql.url=

spring.mysql.username=

#dataSrouceBBB.properties檔案內屬性

spring.sqlserver.url=

spring.sqlserver.username=

二、對由註解生成的相關bean,你需要指定其name。預設spring會將資料來源相關的bean name指定為dataSource、sqlSessionFactory等等。但是對多資料來源來說,你需要主動指定bean name。

三、根據spring boot的規則,你需要使用@Primary首先指定一套預設的資料體系。在本例中,我們將把mysql的資料庫配置作為預設的資料庫配置(後文會標註)。

5、實現

5.1 工程建立

在sts下,選擇新建一個spring bootstarter工程,name為mbbase,type為maven,packaging為war,java version為1.7,language為java,group 為com.zcn,artifact為mbbase,version為0.0.1-SNAPSHOT,package為com.zcn.swc;

“下一步”後,選擇依賴AOP、DevTools、Thymeleaf、Web,(我自己在pom.xml中指定了mybatis、mybatis-spring、mysql、sqlserver等的依賴了);

“完成”後即建立了一個spring-boot工程。

最終,經過手工修改後的pom.xml如下(可能有配置重複不合理的地方,但當前可以執行):


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.zcn</groupId>
	<artifactId>mbbase</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>

	<name>mbbase</name>
	<description>mbbase project for Spring Boot</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.2.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.7</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-aop</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-tomcat</artifactId>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		
		<dependency>
		    <groupId>org.springframework</groupId>
		    <artifactId>spring-tx</artifactId>
		</dependency>
		
		<dependency>
		    <groupId>org.springframework</groupId>
		    <artifactId>spring-jdbc</artifactId>
		</dependency>

		<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
		<dependency>
		    <groupId>org.mybatis</groupId>
		    <artifactId>mybatis</artifactId>
		    <version>3.4.1</version>
		</dependency>
		<dependency>
             <groupId>org.mybatis</groupId>
             <artifactId>mybatis-spring</artifactId>
             <version>1.3.1</version>
         </dependency>   
		<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
		<dependency>
		    <groupId>com.alibaba</groupId>
		    <artifactId>druid</artifactId>
		    <version>1.0.18</version>
		</dependency>
		

		<!-- https://mvnrepository.com/artifact/com.microsoft.sqlserver/sqljdbc4 -->
		<dependency>
		    <groupId>com.microsoft.sqlserver</groupId>
		    <artifactId>sqljdbc4</artifactId>
		    <version>4.0</version>
		</dependency>

		<dependency>
			<groupId>javax.inject</groupId>
			<artifactId>javax.inject</artifactId>
			<version>1</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
			<plugin>  
                <groupId>org.mybatis.generator</groupId>  
                <artifactId>mybatis-generator-maven-plugin</artifactId>  
                <version>1.3.5</version>  
                <configuration>  
                    <overwrite>true</overwrite>  
                </configuration>  
                <dependencies>  
                    <dependency>  
                        <groupId>mysql</groupId>  
                        <artifactId>mysql-connector-java</artifactId>  
                        <version>5.1.30</version>  
                    </dependency>
					<dependency>
						<groupId>com.microsoft.sqlserver</groupId>
						<artifactId>sqljdbc4</artifactId>
						<version>4.0</version>
					</dependency>
                </dependencies>  
            </plugin>  
		</plugins>
	</build>

</project>

5.2 sts中使用mybatis-generator生成entity、mapper及xml等

本步驟是為了生成mybatis方式操作資料庫的相關檔案,與配置多資料來源沒有直接關係,如果你已經能夠在sts內整合並生成相關檔案了,可以跳過此步。

前提:在5.1步pom.xml中,我們已經配置好了mybatis-generator-maven-plugin外掛。已經建立了三個資料庫(一個mysql資料庫名為phpmyadmin,兩個sql server資料庫名為testdb、testdb02)。

首先,我們建立mybatis-generator需要使用的配置檔案。STS的Navigator view下,在/src/main/resources下,新建一個資料夾mbg,在其中建立三個xml檔案:mbg-mysql-phpmyadmin.xml、mbg-sql2v5-testdb.xml、mbg-sql2v5-testdb02.xml(檔案內容在本節之後附),特別注意,xml檔案的格式是utf-8(無BOM)。

然後,以生成mysql-phpmyadmin資料庫的mybatis相關檔案的maven命令為例。右鍵點選mbbase工程,選擇run as…,選擇選單項“Mavenbuild…”;在彈出的“EditConfiguration”對話方塊中,Name設定為“mbtest-mbg-mysql-phpmyadmin”(按習慣起的),Goals設定為:mybatis-generator:generate-Dmybatis.generator.configurationFile=${basedir}/src/main/resources/mbg/mbg-mysql-phpmyadmin.xml-Dmybatis.generator.overwrite=true。若是mbg-mysql-phpmyadmin.xml的內容已經設定好了,就可以點選Run運行了,否則選點選“Apply”儲存吧。對mbbase-mbg-sql2v5-testdb、mbbase-mbg-sql2v5-testdb02,其相應的maven命令設定如下:

// mbbase-mbg-sql2v5-testdb

Name:mbbase-mbg-sql2v5-testdb

Goals:mybatis-generator:generate-Dmybatis.generator.configurationFile=${basedir}/src/main/resources/mbg/mbg-sql2v5-testdb.xml-Dmybatis.generator.overwrite=true

// mbbase-mbg-sql2v5-testdb02

Name:mbbase-mbg-sql2v5-testdb02

Goals:mybatis-generator:generate-Dmybatis.generator.configurationFile=${basedir}/src/main/resources/mbg/mbg-sql2v5-testdb02.xml-Dmybatis.generator.overwrite=true

通過執行以上三個maven命令,即可在com.zcn.swc下生成的domain包內,生成三個子包:phpmyadmin、tesddb、testdb02。其中包含了各自的mapper、model。

注意:生成的MPma_userconfigMapper.xml檔案(mysql中的phpmyadmin庫)內,會出現“phpmyadmin..pma_userconfig”(注意其中的兩個dot),需要全部替換成“phpmyadmin.pma_userconfig”。

附:xml配置檔案

注意,在mysql與sqlserver配置檔案中,有幾個不同:

driverClass不同;

connectionURL不同;

<table>下面的<property>不同,mysql僅需包含一個runtimeCatalog,sqlserver還需包含runtimeSchema,如果不這樣,我這裡生成的***mapper.xml內的sql語句就無法正確執行。

mbg-mysql-phpmyadmin.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration  
  PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"  
  "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">  
<generatorConfiguration>  

    <context id="Mysql_phpmyadmin_Tables"  targetRuntime="MyBatis3">  
        <commentGenerator>  
            <property name="suppressDate" value="true"/>  
            <property name="suppressAllComments" value="true"/>  
        </commentGenerator>  

        <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://127.0.0.1:3306/phpmyadmin" userId="root" password="">  
        </jdbcConnection>  
        <javaTypeResolver>  
            <property name="forceBigDecimals" value="false"/>  
        </javaTypeResolver>  

        <javaModelGenerator targetPackage="com.zcn.swc.domain.phpmyadmin.model" targetProject="src/main/java">  
            <property name="enableSubPackages" value="true"/>  
            <property name="trimStrings" value="true"/>  
        </javaModelGenerator>  

        <sqlMapGenerator targetPackage="com.zcn.swc.domain.phpmyadmin.mapper" targetProject="src/main/java">  
            <property name="enableSubPackages" value="true"/>  
		</sqlMapGenerator>
				
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.zcn.swc.domain.phpmyadmin.mapper" targetProject="src/main/java">  
            <property name="enableSubPackages" value="true"/>  
        </javaClientGenerator>  

        <table tableName="pma_userconfig" domainObjectName="MPma_userconfig" 
        	enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" 
        	enableSelectByExample="false" selectByExampleQueryId="false">
        	<property name="runtimeCatalog" value="phpmyadmin"/>	
        </table>
    </context>  
</generatorConfiguration>  

mbg-sql2v5-testdb.xml


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration  
  PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"  
  "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">  
<generatorConfiguration>  

    <context id="Sql2v5_testdb_Tables"  targetRuntime="MyBatis3">  
        <commentGenerator>  
            <property name="suppressDate" value="true"/>  
            <property name="suppressAllComments" value="true"/>  
        </commentGenerator>  

        <jdbcConnection driverClass="com.microsoft.sqlserver.jdbc.SQLServerDriver" connectionURL="jdbc:sqlserver://127.0.0.1:1433;DatabaseName=testdb;integratedSecurity=false" userId="sa" password="password">  
        </jdbcConnection>  
        <javaTypeResolver>  
            <property name="forceBigDecimals" value="false"/>  
        </javaTypeResolver>  

        <javaModelGenerator targetPackage="com.zcn.swc.domain.testdb.model" targetProject="src/main/java">  
            <property name="enableSubPackages" value="true"/>  
            <property name="trimStrings" value="true"/>  
        </javaModelGenerator>  

        <sqlMapGenerator targetPackage="com.zcn.swc.domain.testdb.mapper" targetProject="src/main/java">  
            <property name="enableSubPackages" value="true"/>  
		</sqlMapGenerator>
				
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.zcn.swc.domain.testdb.mapper" targetProject="src/main/java">  
            <property name="enableSubPackages" value="true"/>  
        </javaClientGenerator>  

        <table tableName="com_member" domainObjectName="MCom_member" 
        	enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" 
        	enableSelectByExample="false" selectByExampleQueryId="false">
        	<property name="runtimeCatalog" value="testdb"/>	
        	<property name="runtimeSchema" value="dbo" />
        </table>
        
    </context>  
</generatorConfiguration>  

mbg-sql2v5-testdb02.xml


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration  
  PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"  
  "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">  
<generatorConfiguration>  

    <context id="Sql2v5_testdb02_Tables"  targetRuntime="MyBatis3">  
        <commentGenerator>  
            <property name="suppressDate" value="true"/>  
            <property name="suppressAllComments" value="true"/>  
        </commentGenerator>  

        <jdbcConnection driverClass="com.microsoft.sqlserver.jdbc.SQLServerDriver" connectionURL="jdbc:sqlserver://127.0.0.1:1433;DatabaseName=testdb02;integratedSecurity=false" userId="sa" password="password">  
        </jdbcConnection>  
        <javaTypeResolver>  
            <property name="forceBigDecimals" value="false"/>  
        </javaTypeResolver>  

        <javaModelGenerator targetPackage="com.zcn.swc.domain.testdb02.model" targetProject="src/main/java">  
            <property name="enableSubPackages" value="true"/>  
            <property name="trimStrings" value="true"/>  
        </javaModelGenerator>  

        <sqlMapGenerator targetPackage="com.zcn.swc.domain.testdb02.mapper" targetProject="src/main/java">  
            <property name="enableSubPackages" value="true"/>  
		</sqlMapGenerator>
				
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.zcn.swc.domain.testdb02.mapper" targetProject="src/main/java">  
            <property name="enableSubPackages" value="true"/>  
        </javaClientGenerator>  

        <table tableName="com_member" domainObjectName="MCom_member" 
        	enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" 
        	enableSelectByExample="false" selectByExampleQueryId="false">
        	<property name="runtimeCatalog" value="testdb02"/>	
        	<property name="runtimeSchema" value="dbo" />
        </table>
        
    </context>  
</generatorConfiguration>  

5.3 多資料來源配置檔案建立

在/src/main/resources下,新建一個資料夾mb,在其中建立三個資料來源的配置檔案:

//mysql-phpmyadmin:

資料來源:mb-mysql-phpmyadmin.properties(檔案格式utf-8無BOM)

mybatis引數:mb-cfg-mysql-phpmyadmin.xml(檔案格式utf-8無BOM)

// sql2v5-testdb:

資料來源:mb-sql2v5-testdb.properties(檔案格式utf-8無BOM)

mybatis引數:mb-cfg- sql2v5-testdb.xml(檔案格式utf-8無BOM)

//sql2v5-testdb02:

資料來源:mb-sql2v5-testdb02.properties(檔案格式utf-8無BOM)

mybatis引數:mb-cfg- sql2v5-testdb02.xml(檔案格式utf-8無BOM)

附:配置檔案內容

mb-mysql-phpmyadmin.properties

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/phpmyadmin?useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=

jdbc.initialSize=5
jdbc.minIdle=5
jdbc.maxActive=20
jdbc.maxWait=60000
jdbc.timeBetweenEvictionRunsMillis=60000
jdbc.minEvictableIdleTimeMillis=300000
jdbc.poolPreparedStatements=true
jdbc.maxPoolPreparedStatementPerConnectionSize=20

jdbc.filters=stat,wall

#mybatis
mybatis.configLocation=classpath:/mb/mb-cfg-mysql-phpmyadmin.xml
mybatis.typeAliasesPackage=com.zcn.swc.domain.phpmyadmin.mapper.phpmyadmin
mybatis.mapperLocations=classpath*:/**/phpmyadmin/mapper/*.xml

mb-cfg-mysql-phpmyadmin.xml


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
    <properties>
        <property name="dialect" value="mysql" />
    </properties>
    <settings>
        <!-- 開啟駝峰匹配 -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        <!-- 這個配置使全域性的對映器啟用或禁用快取。系統預設值是true,設定只是為了展示出來 -->
        <setting name="cacheEnabled" value="true" />
        <!-- 全域性啟用或禁用延遲載入。當禁用時,所有關聯物件都會即時載入。 系統預設值是true,設定只是為了展示出來 -->
        <setting name="lazyLoadingEnabled" value="true" />
        <!-- 允許或不允許多種結果集從一個單獨的語句中返回(需要適合的驅動)。 系統預設值是true,設定只是為了展示出來 -->
        <setting name="multipleResultSetsEnabled" value="true" />
        <!--使用列標籤代替列名。不同的驅動在這方便表現不同。參考驅動文件或充分測試兩種方法來決定所使用的驅動。 系統預設值是true,設定只是為了展示出來 -->
        <setting name="useColumnLabel" value="true" />
        <!--允許 JDBC 支援生成的鍵。需要適合的驅動。如果設定為 true 則這個設定強制生成的鍵被使用,儘管一些驅動拒絕相容但仍然有效(比如 
            Derby)。 系統預設值是false,設定只是為了展示出來 -->
        <setting name="useGeneratedKeys" value="false" />
        <!--配置預設的執行器。SIMPLE 執行器沒有什麼特別之處。REUSE 執行器重用預處理語句。BATCH 執行器重用語句和批量更新 系統預設值是SIMPLE,設定只是為了展示出來 -->
        <setting name="defaultExecutorType" value="SIMPLE" />
        <!--設定超時時間,它決定驅動等待一個數據庫響應的時間。 系統預設值是null,設定只是為了展示出來 -->
        <setting name="defaultStatementTimeout" value="25000" />
    </settings>

	<typeAliases>
		<typeAlias alias="MPma_userconfigMapper" type="com.zcn.swc.domain.phpmyadmin.mapper.phpmyadmin.MPma_userconfigMapper" />
	</typeAliases> 

</configuration>    

mb-sql2v5-testdb.properties


jdbc.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
jdbc.url=jdbc:sqlserver://127.0.0.1:1433;databaseName=testdb;integratedSecurity=false
jdbc.username=sa
jdbc.password=password

jdbc.initialSize=5
jdbc.minIdle=5
jdbc.maxActive=20
jdbc.maxWait=60000
jdbc.timeBetweenEvictionRunsMillis=60000
jdbc.minEvictableIdleTimeMillis=300000
jdbc.poolPreparedStatements=true
jdbc.maxPoolPreparedStatementPerConnectionSize=20

jdbc.filters=stat,wall

#mybatis
mybatis.configLocation=classpath:/mb/mb-cfg-sql2v5-testdb.xml
mybatis.typeAliasesPackage=com.zcn.swc.domain.testdb.model
mybatis.mapperLocations=classpath*:/**/testdb/mapper/*.xml

mb-cfg-sql2v5-testdb.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
    <properties>
        <property name="dialect" value="SQLServer" />
    </properties>
    <settings>
        <!-- 開啟駝峰匹配 -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        <!-- 這個配置使全域性的對映器啟用或禁用快取。系統預設值是true,設定只是為了展示出來 -->
        <setting name="cacheEnabled" value="true" />
        <!-- 全域性啟用或禁用延遲載入。當禁用時,所有關聯物件都會即時載入。 系統預設值是true,設定只是為了展示出來 -->
        <setting name="lazyLoadingEnabled" value="true" />
        <!-- 允許或不允許多種結果集從一個單獨的語句中返回(需要適合的驅動)。 系統預設值是true,設定只是為了展示出來 -->
        <setting name="multipleResultSetsEnabled" value="true" />
        <!--使用列標籤代替列名。不同的驅動在這方便表現不同。參考驅動文件或充分測試兩種方法來決定所使用的驅動。 系統預設值是true,設定只是為了展示出來 -->
        <setting name="useColumnLabel" value="true" />
        <!--允許 JDBC 支援生成的鍵。需要適合的驅動。如果設定為 true 則這個設定強制生成的鍵被使用,儘管一些驅動拒絕相容但仍然有效(比如 
            Derby)。 系統預設值是false,設定只是為了展示出來 -->
        <setting name="useGeneratedKeys" value="false" />
        <!--配置預設的執行器。SIMPLE 執行器沒有什麼特別之處。REUSE 執行器重用預處理語句。BATCH 執行器重用語句和批量更新 系統預設值是SIMPLE,設定只是為了展示出來 -->
        <setting name="defaultExecutorType" value="SIMPLE" />
        <!--設定超時時間,它決定驅動等待一個數據庫響應的時間。 系統預設值是null,設定只是為了展示出來 -->
        <setting name="defaultStatementTimeout" value="25000" />
    </settings>
    
    <typeAliases>
		<typeAlias alias="MCom_memberMapper" type="com.zcn.swc.domain.testdb.mapper.testdb.dbo.MCom_memberMapper" />		
	</typeAliases> 

</configuration>    

mb-sql2v5-testdb02.properties


jdbc.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
jdbc.url=jdbc:sqlserver://127.0.0.1:1433;databaseName=testdb02;integratedSecurity=false
jdbc.username=sa
jdbc.password=password

jdbc.initialSize=5
jdbc.minIdle=5
jdbc.maxActive=20
jdbc.maxWait=60000
jdbc.timeBetweenEvictionRunsMillis=60000
jdbc.minEvictableIdleTimeMillis=300000
jdbc.poolPreparedStatements=true
jdbc.maxPoolPreparedStatementPerConnectionSize=20

jdbc.filters=stat,wall

#mybatis
mybatis.configLocation=classpath:/mb/mb-cfg-sql2v5-testdb02.xml
mybatis.typeAliasesPackage=com.zcn.swc.domain.testdb02.model
mybatis.mapperLocations=classpath*:/**/testdb02/mapper/*.xml

mb-cfg- sql2v5-testdb02.xml


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
    <properties>
        <property name="dialect" value="SQLServer" />
    </properties>
    <settings>
        <!-- 開啟駝峰匹配 -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        <!-- 這個配置使全域性的對映器啟用或禁用快取。系統預設值是true,設定只是為了展示出來 -->
        <setting name="cacheEnabled" value="true" />
        <!-- 全域性啟用或禁用延遲載入。當禁用時,所有關聯物件都會即時載入。 系統預設值是true,設定只是為了展示出來 -->
        <setting name="lazyLoadingEnabled" value="true" />
        <!-- 允許或不允許多種結果集從一個單獨的語句中返回(需要適合的驅動)。 系統預設值是true,設定只是為了展示出來 -->
        <setting name="multipleResultSetsEnabled" value="true" />
        <!--使用列標籤代替列名。不同的驅動在這方便表現不同。參考驅動文件或充分測試兩種方法來決定所使用的驅動。 系統預設值是true,設定只是為了展示出來 -->
        <setting name="useColumnLabel" value="true" />
        <!--允許 JDBC 支援生成的鍵。需要適合的驅動。如果設定為 true 則這個設定強制生成的鍵被使用,儘管一些驅動拒絕相容但仍然有效(比如 
            Derby)。 系統預設值是false,設定只是為了展示出來 -->
        <setting name="useGeneratedKeys" value="false" />
        <!--配置預設的執行器。SIMPLE 執行器沒有什麼特別之處。REUSE 執行器重用預處理語句。BATCH 執行器重用語句和批量更新 系統預設值是SIMPLE,設定只是為了展示出來 -->
        <setting name="defaultExecutorType" value="SIMPLE" />
        <!--設定超時時間,它決定驅動等待一個數據庫響應的時間。 系統預設值是null,設定只是為了展示出來 -->
        <setting name="defaultStatementTimeout" value="25000" />
    </settings>
    
    <typeAliases>
		<typeAlias alias="MCom_memberMapper" type="com.zcn.swc.domain.testdb02.mapper.testdb02.dbo.MCom_memberMapper" />		
	</typeAliases> 

</configuration>    

5.4 建立三個mybatis config類

本步驟是spring boot內配置多個mybatis資料來源的最後一步。

首先,在com.zcn.swc下新建一個包common,然後建立三個config類:

MyBatis_Mysql_phpmyadmin_Config;

MyBatis_Sql2v5_testdb_Config;

MyBatis_Sql2v5_testdb02_Config;

在後面附的程式碼中,需要注意:

一、MyBatis_Mysql_phpmyadmin_Config類中的bean使用了@Primary註解;

二、mapperScannerConfigurer方法上,使用了@DependsOn註解。

以上兩個非常關鍵,一是為了滿足spring boot的預設規則,二是為了滿足建立bean的順序。

附:三個類檔案:

// MyBatis_Mysql_phpmyadmin_Config

package com.zcn.swc.common;

import java.io.IOException;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import com.alibaba.druid.pool.DruidDataSource;

@Configuration 
public class MyBatis_Mysql_phpmyadmin_Config { 
	
	Properties _propsConfig = new Properties();
	
	public MyBatis_Mysql_phpmyadmin_Config() {
		// TODO Auto-generated constructor stub
        
        String filename = "mb/mb-mysql-phpmyadmin.properties";  
        try {
			_propsConfig.load(MyBatis_Mysql_phpmyadmin_Config.class.getClassLoader().getResourceAsStream(filename));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}          
	}

    @Bean(name = "dataSource_mysql_phpmyadmin")
    @Primary
    public DataSource dataSource() throws Exception{
        Properties props = new Properties();

        DruidDataSource objDs = new DruidDataSource();
        
        props.put("driverClassName", _propsConfig.getProperty("jdbc.driverClassName"));
        props.put("url", _propsConfig.getProperty("jdbc.url"));
        props.put("username", _propsConfig.getProperty("jdbc.username"));
        props.put("password", _propsConfig.getProperty("jdbc.password"));
        props.put("initialSize", _propsConfig.getProperty("jdbc.initialSize"));
        props.put("minIdle", _propsConfig.getProperty("jdbc.minIdle"));
        props.put("maxActive", _propsConfig.getProperty("jdbc.maxActive"));
        props.put("maxWait", _propsConfig.getProperty("jdbc.maxWait"));
        props.put("timeBetweenEvictionRunsMillis", _propsConfig.getProperty("jdbc.timeBetweenEvictionRunsMillis"));
        props.put("minEvictableIdleTimeMillis", _propsConfig.getProperty("jdbc.minEvictableIdleTimeMillis"));
        props.put("maxPoolPreparedStatementPerConnectionSize", _propsConfig.getProperty("jdbc.maxPoolPreparedStatementPerConnectionSize"));
        props.put("filters", _propsConfig.getProperty("jdbc.filters"));
        
        objDs.setUrl(props.getProperty("url"));
        objDs.setDriverClassName(props.getProperty("driverClassName"));
        objDs.setUsername(props.getProperty("username"));
        objDs.setPassword(props.getProperty("password"));
        objDs.setInitialSize(Integer.valueOf(props.getProperty("initialSize")));
        objDs.setMinIdle(Integer.valueOf(props.getProperty("maxActive")));
        objDs.setMaxWait(Long.valueOf(props.getProperty("maxWait")));
        objDs.setMaxActive(Integer.valueOf(props.getProperty("maxActive")));
        objDs.setMinEvictableIdleTimeMillis(Long.valueOf(props.getProperty("minEvictableIdleTimeMillis")));

        try {
        	objDs.setFilters(props.getProperty("filters"));
        } catch (Exception e) {
            e.printStackTrace();
        }       
        
        return objDs;
    }

    @Bean(name = "sqlSessionFactory_mysql_phpmyadmin")
    @Primary
    //@ConditionalOnMissingBean 
    public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource_mysql_phpmyadmin") DataSource dataSource_mysql_phpmyadmin) throws Exception{
    	try {  
            SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();  
            sessionFactory.setDataSource(dataSource_mysql_phpmyadmin);  
            sessionFactory.setConfigLocation(new PathMatchingResourcePatternResolver().getResources(_propsConfig.getProperty("mybatis.configLocation"))[0]);
            sessionFactory.setTypeAliasesPackage(_propsConfig.getProperty("mybatis.typeAliasesPackage"));  
            sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(_propsConfig.getProperty("mybatis.mapperLocations")));
            
            return sessionFactory.getObject(); 
        } catch (Exception e) {  
            return null;  
        }  
    }
    
    @Bean(name="sqlSessionTemplate_mysql_phpmyadmin")
    @Primary
    public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlSessionFactory_mysql_phpmyadmin") SqlSessionFactory sqlSessionFactory_mysql_phpmyadmin) {
    	SqlSessionTemplate obj = new SqlSessionTemplate(sqlSessionFactory_mysql_phpmyadmin);
        return obj;
    }
    
	@Bean(name="mapperScanner_mysql_phpmyadmin")
	@Primary
    @DependsOn({"sqlSessionFactory_mysql_phpmyadmin", "sqlSessionTemplate_mysql_phpmyadmin"})
    public MapperScannerConfigurer mapperScannerConfigurer() {
        MapperScannerConfigurer obj = new MapperScannerConfigurer();
        obj.setBasePackage("com.zcn.swc.domain.phpmyadmin.mapper");
        obj.setSqlSessionFactoryBeanName("sqlSessionFactory_mysql_phpmyadmin");
        obj.setSqlSessionTemplateBeanName("sqlSessionTemplate_mysql_phpmyadmin");
        obj.setBeanName("mapperScanner_mysql_phpmyadmin");
        return obj;
    }

    @Bean(name="transactionManager_mysql_phpmyadmin")
    public DataSourceTransactionManager transactionManager(@Qualifier("dataSource_mysql_phpmyadmin") DataSource dataSource_mysql_phpmyadmin) {
      return new DataSourceTransactionManager(dataSource_mysql_phpmyadmin);
    }

}

// MyBatis_Sql2v5_testdb_Config


package com.zcn.swc.common;

import java.io.IOException;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import com.alibaba.druid.pool.DruidDataSource;


@Configuration    
public class MyBatis_Sql2v5_testdb_Config { 
	
	Properties _propsConfig = new Properties();
	
	public MyBatis_Sql2v5_testdb_Config() {
		// TODO Auto-generated constructor stub
        
        String filename = "mb/mb-sql2v5-testdb.properties";  
        try {
			_propsConfig.load(MyBatis_Sql2v5_testdb_Config.class.getClassLoader().getResourceAsStream(filename));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}          
	}
	
    @Bean(name = "dataSource_sql2v5_testdb")
    public DataSource dataSource() throws Exception{
        Properties props = new Properties();

        DruidDataSource objDs = new DruidDataSource();
        
        props.put("driverClassName", _propsConfig.getProperty("jdbc.driverClassName"));
        props.put("url", _propsConfig.getProperty("jdbc.url"));
        props.put("username", _propsConfig.getProperty("jdbc.username"));
        props.put("password", _propsConfig.getProperty("jdbc.password"));
        props.put("initialSize", _propsConfig.getProperty("jdbc.initialSize"));
        props.put("minIdle", _propsConfig.getProperty("jdbc.minIdle"));
        props.put("maxActive", _propsConfig.getProperty("jdbc.maxActive"));
        props.put("maxWait", _propsConfig.getProperty("jdbc.maxWait"));
        props.put("timeBetweenEvictionRunsMillis", _propsConfig.getProperty("jdbc.timeBetweenEvictionRunsMillis"));
        props.put("minEvictableIdleTimeMillis", _propsConfig.getProperty("jdbc.minEvictableIdleTimeMillis"));
        props.put("maxPoolPreparedStatementPerConnectionSize", _propsConfig.getProperty("jdbc.maxPoolPreparedStatementPerConnectionSize"));
        props.put("filters", _propsConfig.getProperty("jdbc.filters"));
        
        objDs.setUrl(props.getProperty("url"));
        objDs.setDriverClassName(props.getProperty("driverClassName"));
        objDs.setUsername(props.getProperty("username"));
        objDs.setPassword(props.getProperty("password"));
        objDs.setInitialSize(Integer.valueOf(props.getProperty("initialSize")));
        objDs.setMinIdle(Integer.valueOf(props.getProperty("maxActive")));
        objDs.setMaxWait(Long.valueOf(props.getProperty("maxWait")));
        objDs.setMaxActive(Integer.valueOf(props.getProperty("maxActive")));
        objDs.setMinEvictableIdleTimeMillis(Long.valueOf(props.getProperty("minEvictableIdleTimeMillis")));

        try {
        	objDs.setFilters(props.getProperty("filters"));
        } catch (Exception e) {
            e.printStackTrace();
        }       
        
        return objDs;
    }

    @Bean(name = "sqlSessionFactory_sql2v5_testdb")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource_sql2v5_testdb") DataSource dataSource_sql2v5_testdb) throws Exception{
    	try {  
            SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();  
            sessionFactory.setDataSource(dataSource_sql2v5_testdb);  
            sessionFactory.setConfigLocation(new PathMatchingResourcePatternResolver().getResources(_propsConfig.getProperty("mybatis.configLocation"))[0]);
            sessionFactory.setTypeAliasesPackage(_propsConfig.getProperty("mybatis.typeAliasesPackage"));  
            sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(_propsConfig.getProperty("mybatis.mapperLocations")));
            
            return sessionFactory.getObject(); 
        } catch (Exception e) {  
            return null;  
        }  
    }
    
    @Bean(name="sqlSessionTemplate_sql2v5_testdb")
    public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlSessionFactory_sql2v5_testdb") SqlSessionFactory sqlSessionFactory_sql2v5_testdb) {
    	SqlSessionTemplate obj = new SqlSessionTemplate(sqlSessionFactory_sql2v5_testdb);
        return obj;
    }
    
	@Bean(name="mapperScanner_sql2v5_testdb")
    @DependsOn({"sqlSessionFactory_sql2v5_testdb", "sqlSessionTemplate_sql2v5_testdb"})
    public MapperScannerConfigurer mapperScannerConfigurer() {
        MapperScannerConfigurer obj = new MapperScannerConfigurer();
        obj.setBasePackage("com.zcn.swc.domain.testdb.mapper");
        obj.setSqlSessionFactoryBeanName("sqlSessionFactory_sql2v5_testdb");
        obj.setSqlSessionTemplateBeanName("sqlSessionTemplate_sql2v5_testdb");
        obj.setBeanName("mapperScanner_sql2v5_testdb");
        return obj;
    }

    @Bean(name="transactionManager_sql2v5_testdb")
    public DataSourceTransactionManager transactionManager(@Qualifier("dataSource_sql2v5_testdb") DataSource dataSource_sql2v5_testdb) {
      return new DataSourceTransactionManager(dataSource_sql2v5_testdb);
    }

}

// MyBatis_Sql2v5_testdb02_Config


package com.zcn.swc.common;

import java.io.IOException;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import com.alibaba.druid.pool.DruidDataSource;


@Configuration    
public class MyBatis_Sql2v5_testdb02_Config { 
	
	Properties _propsConfig = new Properties();
	
	public MyBatis_Sql2v5_testdb02_Config() {
		// TODO Auto-generated constructor stub
        
        String filename = "mb/mb-sql2v5-testdb02.properties";  
        try {
			_propsConfig.load(MyBatis_Sql2v5_testdb02_Config.class.getClassLoader().getResourceAsStream(filename));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}          
	}
	
    @Bean(name = "dataSource_sql2v5_testdb02")
    public DataSource dataSource() throws Exception{
        Properties props = new Properties();

        DruidDataSource objDs = new DruidDataSource();
        
        props.put("driverClassName", _propsConfig.getProperty("jdbc.driverClassName"));
        props.put("url", _propsConfig.getProperty("jdbc.url"));
        props.put("username", _propsConfig.getProperty("jdbc.username"));
        props.put("password", _propsConfig.getProperty("jdbc.password"));
        props.put("initialSize", _propsConfig.getProperty("jdbc.initialSize"));
        props.put("minIdle", _propsConfig.getProperty("jdbc.minIdle"));
        props.put("maxActive", _propsConfig.getProperty("jdbc.maxActive"));
        props.put("maxWait", _propsConfig.getProperty("jdbc.maxWait"));
        props.put("timeBetweenEvictionRunsMillis", _propsConfig.getProperty("jdbc.timeBetweenEvictionRunsMillis"));
        props.put("minEvictableIdleTimeMillis", _propsConfig.getProperty("jdbc.minEvictableIdleTimeMillis"));
        props.put("maxPoolPreparedStatementPerConnectionSize", _propsConfig.getProperty("jdbc.maxPoolPreparedStatementPerConnectionSize"));
        props.put("filters", _propsConfig.getProperty("jdbc.filters"));
        
        objDs.setUrl(props.getProperty("url"));
        objDs.setDriverClassName(props.getProperty("driverClassName"));
        objDs.setUsername(props.getProperty("username"));
        objDs.setPassword(props.getProperty("password"));
        objDs.setInitialSize(Integer.valueOf(props.getProperty("initialSize")));
        objDs.setMinIdle(Integer.valueOf(props.getProperty("maxActive")));
        objDs.setMaxWait(Long.valueOf(props.getProperty("maxWait")));
        objDs.setMaxActive(Integer.valueOf(props.getProperty("maxActive")));
        objDs.setMinEvictableIdleTimeMillis(Long.valueOf(props.getProperty("minEvictableIdleTimeMillis")));

        try {
        	objDs.setFilters(props.getProperty("filters"));
        } catch (Exception e) {
            e.printStackTrace();
        }       
        
        return objDs;
    }

    @Bean(name = "sqlSessionFactory_sql2v5_testdb02")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource_sql2v5_testdb02") DataSource dataSource_sql2v5_testdb02) throws Exception{
    	try {  
            SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();  
            sessionFactory.setDataSource(dataSource_sql2v5_testdb02);  
            sessionFactory.setConfigLocation(new PathMatchingResourcePatternResolver().getResources(_propsConfig.getProperty("mybatis.configLocation"))[0]);
            sessionFactory.setTypeAliasesPackage(_propsConfig.getProperty("mybatis.typeAliasesPackage"));  
            sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(_propsConfig.getProperty("mybatis.mapperLocations")));
            
            return sessionFactory.getObject(); 
        } catch (Exception e) {  
            return null;  
        }  
    }
    
    @Bean(name="sqlSessionTemplate_sql2v5_testdb02")
    public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlSessionFactory_sql2v5_testdb02") SqlSessionFactory sqlSessionFactory_sql2v5_testdb02) {
    	SqlSessionTemplate obj = new SqlSessionTemplate(sqlSessionFactory_sql2v5_testdb02);
        return obj;
    }
    
	@Bean(name="mapperScanner_sql2v5_testdb02")
    @DependsOn({"sqlSessionFactory_sql2v5_testdb02", "sqlSessionTemplate_sql2v5_testdb02"})
    public MapperScannerConfigurer mapperScannerConfigurer() {
        MapperScannerConfigurer obj = new MapperScannerConfigurer();
        obj.setBasePackage("com.zcn.swc.domain.testdb02.mapper");
        obj.setSqlSessionFactoryBeanName("sqlSessionFactory_sql2v5_testdb02");
        obj.setSqlSessionTemplateBeanName("sqlSessionTemplate_sql2v5_testdb02");
        obj.setBeanName("mapperScanner_sql2v5_testdb02");
        return obj;
    }

    @Bean(name="transactionManager_sql2v5_testdb02")
    public DataSourceTransactionManager transactionManager(@Qualifier("dataSource_sql2v5_testdb02") DataSource dataSource_sql2v5_testdb02) {
      return new DataSourceTransactionManager(dataSource_sql2v5_testdb02);
    }

}


6、測試

一、com.zcn.swc.domain.phpmyadmin包下建立一個servier包,在其下新建一個類:PmaUserconfigService,程式碼如下:

package com.zcn.swc.domain.phpmyadmin.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.zcn.swc.domain.phpmyadmin.mapper.phpmyadmin.MPma_userconfigMapper;
import com.zcn.swc.domain.phpmyadmin.model.phpmyadmin.MPma_userconfig;

@Service
public class PmaUserconfigService {
	
	@Autowired
	private MPma_userconfigMapper mPma_userconfigMapper;
	
	public MPma_userconfig getUserconfig(String strUsername) {
		return this.mPma_userconfigMapper.selectByPrimaryKey(strUsername);
	}
}

二、com.zcn.swc.domain.testdb包下建立一個servier包,在其下新建一個類:MemberService,程式碼如下:

package com.zcn.swc.domain.testdb.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.zcn.swc.domain.testdb.mapper.testdb.dbo.MCom_memberMapper;
import com.zcn.swc.domain.testdb.model.testdb.dbo.MCom_member;

@Service("testdbMemberService")
public class MemberService {
	@Autowired
	private MCom_memberMapper mCom_memberMapper;
	
	public MCom_member getMember(String strId) {
		return this.mCom_memberMapper.selectByPrimaryKey(strId);
	}
}

三、com.zcn.swc.domain.testdb02包下建立一個servier包,在其下新建一個類:MemberService,程式碼如下(注意此步中的mapper成員使用了@Qualifier註解):

package com.zcn.swc.domain.testdb02.service;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.zcn.swc.domain.testdb02.mapper.testdb02.dbo.MCom_memberMapper;
import com.zcn.swc.domain.testdb02.model.testdb02.dbo.MCom_member;


@Service("testdb02MemberService")
public class MemberService {

	@Autowired
	@Qualifier("MCom_memberMapper02_test")
	private MCom_memberMapper mCom_memberMapper;
	
	public MCom_member getMember(String strId) {
		return this.mCom_memberMapper.selectByPrimaryKey(strId);
	}
}

四、在com.zcn.swc.domain.testdb02.mapper.testdb02.dbo.MCom_memberMapper介面定義前,新增@Named註解,如下:

package com.zcn.swc.domain.testdb02.mapper.testdb02.dbo;

import javax.inject.Named;

import com.zcn.swc.domain.testdb02.model.testdb02.dbo.MCom_member;

@Named("MCom_memberMapper02_test")
public interface MCom_memberMapper {
    int deleteByPrimaryKey(String id);

    int insert(MCom_member record);

    int insertSelective(MCom_member record);

    MCom_member selectByPrimaryKey(String id);

    int updateByPrimaryKeySelective(MCom_member record);

    int updateByPrimaryKey(MCom_member record);
}

五、在com.zcn.swc下新建一個包controller,在其中建立一個Controller類MemberController,程式碼如下:

package com.zcn.swc.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import com.zcn.swc.domain.phpmyadmin.model.phpmyadmin.MPma_userconfig;
import com.zcn.swc.domain.phpmyadmin.service.PmaUserconfigService;


@Controller
public class MemberController {

	@Autowired
	private PmaUserconfigService pmaUserconfigService;
	
	@Autowired
	@Qualifier("testdbMemberService")
	private com.zcn.swc.domain.testdb.service.MemberService memberService;
	
	@Autowired
	@Qualifier("testdb02MemberService")
	private com.zcn.swc.domain.testdb02.service.MemberService memberService02;
	
	@RequestMapping(value="/getMember")
	public String getHyxxById(Model model) {
		String strRet = "member";
		
		// phpmyadmin info
		MPma_userconfig objRetMysqlPhpmyadmin = pmaUserconfigService.getUserconfig("root");
		
		// sql2v5 testdb member info
		String strId = "21223fc4-8140-4c2a-9a02-ae1c539fcc1f";
		com.zcn.swc.domain.testdb.model.testdb.dbo.MCom_member objRetTestDb = memberService.getMember(strId);
		
		// sql2v5 testdb02 member info
		String strId02 = "1ac7ed1e-2f73-4190-b48b-5fa122a8ba00";
		com.zcn.swc.domain.testdb02.model.testdb02.dbo.MCom_member objRetTestDb02 = memberService02.getMember(strId02);

		model.addAttribute("testdb", objRetTestDb);
		model.addAttribute("testdb02", objRetTestDb02);
		model.addAttribute("mysql", objRetMysqlPhpmyadmin);
		return strRet;
	} 
}

七、在/src/main/resources/templates下,新建一個member.html檔案:

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Getting Started: Serving Web Content</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
    <p th:text="'mysql-phpmyadmin username : ' + ${mysql.getUsername()} + '!'" />
    <p th:text="'sql2v5-testdb username : ' + ${testdb.getUsername()} + '!'" />
    <p th:text="'sql2v5-testdb02 username : ' + ${testdb02.getUsername()} + '!'" />
</body>
</html>

八、在/src/main/resource/application.properties內新增如下配置(本步驟也可以省去,與url請求有關):

server.contextPath=/mbbase/

九、右鍵點選mbbase工程,在Run As內選擇Spring Boot App,等待工程自動生成並開啟內建tomcat;

最終會看到三條結果。


7、附sql指令碼:

//mysql-phpmyadmin

-- Database: phpmyadmin
CREATE TABLE `pma_userconfig` (
  `username` varchar(64) COLLATE utf8_bin NOT NULL,
  `timevalue` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `config_data` text COLLATE utf8_bin NOT NULL,
  PRIMARY KEY (`username`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='User preferences storage for phpMyAdmin';

INSERT INTO `pma_userconfig` VALUES ('root','2015-12-13 07:30:58','{\"lang\":\"zh_CN\"}');

// sql2v5-testdb

-- Database: testdb
CREATE TABLE [dbo].[com_member](
	[id] [uniqueidentifier] NOT NULL,
	[username] [varchar](64) NULL,
	[password] [varchar](64) NULL,
	[salt] [varchar](16) NULL,
	[email] [varchar](128) NULL,
	[membertype] [int] NULL,
	[lockstate] [int] NULL,
	[staffid] [uniqueidentifier] NULL,
	[begindate] [int] NULL DEFAULT ([dbo].[getIntCurrentDate]()),
	[enddate] [int] NULL,
	[flag] [int] NULL,
	[remark] [varchar](256) NULL,
	[createid] [uniqueidentifier] NULL,
	[createdate] [int] NULL DEFAULT ([dbo].[getIntCurrentDate]()),
	[createtime] [int] NULL DEFAULT ([dbo].[getIntCurrentTime]()),
	[updateid] [uniqueidentifier] NULL,
	[updatedate] [int] NULL,
	[updatetime] [int] NULL,
	[delid] [uniqueidentifier] NULL,
	[deldate] [int] NULL,
	[deltime] [int] NULL,
 CONSTRAINT [PK_COM_MEMBER] PRIMARY KEY CLUSTERED 
(
	[id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

insert into com_member(id, username, password, salt)  VALUES ('21223fc4-8140-4c2a-9a02-ae1c539fcc1f', 'system', 'R294c3a2XzOOrIjHZOSG9qSsnW6fVh2+', '123456');

// sql2v5-testdb02

-- Database: testdb02
CREATE TABLE [dbo].[com_member](
	[id] [uniqueidentifier] NOT NULL,
	[username] [varchar](64) NULL,
	[password] [varchar](64) NULL,
	[salt] [varchar](16) NULL,
	[email] [varchar](128) NULL,
	[membertype] [int] NULL,
	[lockstate] [int] NULL,
	[staffid] [uniqueidentifier] NULL,
	[begindate] [int] NULL DEFAULT ([dbo].[getIntCurrentDate]()),
	[enddate] [int] NULL,
	[flag] [int] NULL,
	[remark] [varchar](256) NULL,
	[createid] [uniqueidentifier] NULL,
	[createdate] [int] NULL DEFAULT ([dbo].[getIntCurrentDate]()),
	[createtime] [int] NULL DEFAULT ([dbo].[getIntCurrentTime]()),
	[updateid] [uniqueidentifier] NULL,
	[updatedate] [int] NULL,
	[updatetime] [int] NULL,
	[delid] [uniqueidentifier] NULL,
	[deldate] [int] NULL,
	[deltime] [int] NULL,
 CONSTRAINT [PK_COM_MEMBER] PRIMARY KEY CLUSTERED 
(
	[id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

insert into com_member(id, username, password, salt)  VALUES ('1ac7ed1e-2f73-4190-b48b-5fa122a8ba00', 'core02', 'MV8/+oYf8J4moKBhay4O6ObegzZxJrnt+', '123456');

8、參考或有用的連結

9、工程下載:工程下載