// 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;
十、打开浏览器,输入:http://localhost:8080/mbbase/getMember;
最终会看到三条结果。
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、参考或有用的链接
第五章 springboot + mybatis:http://www.cnblogs.com/java-zhao/p/5350021.html
Building theConnection URL:https://docs.microsoft.com/en-us/sql/connect/jdbc/building-the-connection-url
关于jdbc的数据库驱动类DriverManager.getConnection()参数:http://blog.sina.com.cn/s/blog_9653ee0f0101ji7s.html
Spring Boot -Environment @Autowired throws NullPointerExceptio:http://stackoverflow.com/questions/19454289/spring-boot-environment-autowired-throws-nullpointerexception
mybatis整合spring报java.lang.AbstractMethodError:org.mybatis.spring.transaction:http://blog.youkuaiyun.com/zljava2009/article/details/52092358
Spring BootMultiple Datasource:http://stackoverflow.com/questions/27614301/spring-boot-multiple-datasource
Spring Boot下配置MyBatis多数据源:http://blog.youkuaiyun.com/asdfsfsdgdfgh/article/details/51481911
[Java][MyBatis]mapperLocations属性通配符的使用:http://blog.youkuaiyun.com/szwangdf/article/details/23432783
mybatis-generator重新生成代码时的SQL映射文件覆盖:http://www.ithao123.cn/content-7476250.html
com.microsoft.sqlserver.jdbc.SQLServerException:对象名 ‘xxx' 无效:http://blog.youkuaiyun.com/pcdaan/article/details/6524472
数据库schema与catalog的理解:http://blog.youkuaiyun.com/nash603/article/details/40506713
MyBatisGenerator XML 配置参考:http://blog.youkuaiyun.com/gzg1001/article/details/51935948
Result Mapscollection already contains value for xxxMapper.BaseResultMap错误解决办法:http://blog.youkuaiyun.com/ldl22847/article/details/50390919
Spring Boot导入XML配置【从零开始学Spring Boot】:http://412887952-qq-com.iteye.com/blog/2293846
SSM:spring+springmvc+mybatis框架中的XML配置文件功能详细解释:http://blog.youkuaiyun.com/yijiemamin/article/details/51156189
Distributedtransactions with multiple databases, Spring Boot, Spring Data JPA and Atomikos:http://fabiomaffioletti.me/blog/2014/04/15/distributed-transactions-multiple-databases-spring-boot-spring-data-jpa-atomikos/
Spring中depends-on属性:http://chenfeng0104.iteye.com/blog/757875
javax.inject中@Inject、@Named、@Qualifier和@Provider用法:http://blog.youkuaiyun.com/binxigogo/article/details/7851924
MybatisMapperScannerConfigurer 自动扫描 将Mapper接口生成代理注入到Spring:http://www.cnblogs.com/daxin/p/3545040.html
9、工程下载: 工程下载