由于公司项目中用到了多数据源,所以在配置项目的时候需要加入多数据源的支持,采用的是DruidDataSource数据源和mybaitis配合使用,这里将配置过程记录下来以便增加记忆。
1.创建一个springboot web项目
这里使用的版本
- springboot 1.5.14.RELEASE
- jdk1.8
创建好项目后,调整一下结构,如图所示
2.添加需要的jar包
1)druid数据源 druid-1.1.2.jar
2)参数绑定需要的jar spring-boot-configuration-processor-1.5.14.RELEASE.jar
3)最终的pom内容为:
<?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.example</groupId>
<artifactId>multipeldatasource</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>multipeldatasource</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.14.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.8</java.version>
<druid.version>1.1.2</druid.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3.配置数据源属性
编写application.yml,配置属性如下
spring:
datasource:
db1:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/db1
username: root
password: 123456
db2:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/db2
username: root
password: 123456
上面配置了两个数据源,db1和db2分别对应两个数据库,当然你可以配置更多,到此为止,数据源配置完成,但是,这个时候,我们的程序是无法读取这些数据源的,我们还需要最后的一步配置
4.数据源配置类
1)创建DataSourcesConfig_db1类
配置数据源,事物管理器并指定此数据源的mapper所在路径和maybaits的配置路径
/**
* db1数据源的配置
* @author zzt
*
*/
@Configuration
@MapperScan(basePackages = DataSourcesConfig_db1.PACKAGES, sqlSessionFactoryRef = "sqlSessionFactory_db1")
public class DataSourcesConfig_db1 {
/**
* mapper所在的包路径
*/
public static final String PACKAGES = "com.example.demo.mapper.db1";
/**
* mapper类对应的xml
*/
private static final String MAPPER_LOCAL = "classpath:mapper/db1/*.xml";
/**
* 配置DataSource
* @return
*/
@ConfigurationProperties("spring.datasource.db1")
@Primary
@Bean(name = "dataSource_db1")
public DruidDataSource druidDataSource() {
return new DruidDataSource();
}
/**
* 配置事物管理器
* @return
*/
@Bean(name = "transactionManager_db1")
@Primary
public DataSourceTransactionManager masterTransactionManager(@Qualifier("dataSource_db1") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
/**
* SqlSessionFactory配置
*
* @return
* @throws Exception
*/
@Bean(name = "sqlSessionFactory_db1")
@Primary
public SqlSessionFactory masterSqlSessionFactory(@Qualifier("dataSource_db1") DataSource dataSource) throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCAL));
// 加载全局的配置文件
sqlSessionFactoryBean.setConfigLocation(new DefaultResourceLoader().getResource("classpath:public/db1/mybatis-configuration.xml"));
return sqlSessionFactoryBean.getObject();
}
}
需要说明的是,在配置多个数据源的时候,一定要指定一个数据源为[@Primary](https://my.oschina.net/primary),如果不声明一个数据源为@Primary启动的时候就会提示有多个数据源;所以在配置db2等其他数据源和事物的时候就不需要在声明为@Primary了!
因为我使用的是mybaitis所以在配置数据源的时候同时指定了此数据源下mapper所在的位置和mybaitis的配置文件路径,同时也配置了事物管理器。
2)同样的方式创建DataSourcesConfig_db2类,并配置对应的mapper和事物管理器,mybaitis配置文件等信息
/**
* db2的数据源配置
* @author zzt
*
*/
@Configuration
@MapperScan(basePackages = DataSourcesConfig_db2.PACKAGES, sqlSessionFactoryRef = "sqlSessionFactory_db2")
public class DataSourcesConfig_db2 {
/**
* mapper所在的包路径
*/
public static final String PACKAGES = "com.example.demo.mapper.db2";
/**
* mapper类对应的xml
*/
private static final String MAPPER_LOCAL = "classpath:mapper/db2/*.xml";
/**
* 配置DataSource
* @return
*/
@ConfigurationProperties("spring.datasource.db2")
@Bean(name = "dataSource_db2")
public DruidDataSource DataSource() {
return new DruidDataSource();
}
/**
* 配置事物管理器
* @return
*/
@Bean(name = "transactionManager_db2")
public DataSourceTransactionManager db2TransactionManager(@Qualifier("dataSource_db2") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
/**
* SqlSessionFactory配置
*
* @return
* @throws Exception
*/
@Bean(name = "sqlSessionFactory_db2")
public SqlSessionFactory db2SqlSessionFactory(@Qualifier("dataSource_db2") DataSource dataSource) throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCAL));
// 加载全局的配置文件
sqlSessionFactoryBean.setConfigLocation(new DefaultResourceLoader().getResource("classpath:public/db2/mybatis-configuration.xml"));
return sqlSessionFactoryBean.getObject();
}
}
3)最后创建mapper和mybaitis配置文件
创建db1的mapper和对应的xml 为了简单说明,我们使用User对象查询一个用户信息
- UserMapper_db1:
import com.example.demo.entity.User;
/**
* @author zzt
* 注(不同数据源下的mapper名字一样需要加别名以区分,不然启动报错)
*/
public interface UserMapper_db1 {
public User findUser();
}
- UserMapper_db1.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.db1.UserMapper_db1">
<!-- 查询用户信息 -->
<select id="findUser" resultType="com.example.demo.entity.User">
select * from usertable where id = '1111'
</select>
</mapper>
- db1数据源的mybaitis配置 mybatis-configuration.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>
<!--整合Spring的时候 只有 settings typeAliases mapper 三个属性有用, 其余的要在spring总配置文件中会覆盖-->
<!--<settings>
<setting name="cacheEnabled" value="false" />
<setting name="defaultExecutorType" value="REUSE" /> <!– 使用预处理执行器 –>
<setting name="defaultStatementTimeout" value="25" />
<setting name="localCacheScope" value="SESSION" />
<setting name="callSettersOnNulls" value="true"/>
</settings>-->
<!-- 设置运行参数 -->
<settings>
<!-- 全局映射器启用缓存 -->
<setting name="cacheEnabled" value="true" />
<!-- 查询时,关闭关联对象及时加载以提高性能 -->
<setting name="lazyLoadingEnabled" value="false" />
<!-- 设置关联对象加载的形态,此处为按需加载字段(加载字段由SQL指定),不会加载关联表的所有字段,以提高性能 -->
<setting name="aggressiveLazyLoading" value="false" />
<!-- 对于位置的SQL查询,允许返回不同的结果集以达到通用的效果 -->
<setting name="multipleResultSetsEnabled" value="true" />
<!-- 允许使用列标签代替列明 -->
<setting name="useColumnLabel" value="true" />
<!-- 允许使用自定义的主键值(比如由程序生成的UUID 32位编码作为键值), 数据表的pk生成策略将被覆盖 -->
<setting name="useGeneratedKeys" value="true" />
<!-- 给予被嵌套的resultMap以字段-属性的映射支持 -->
<setting name="autoMappingBehavior" value="PARTIAL" />
<!-- 对于批量更新操作缓存SQL以提高性能 -->
<setting name="defaultExecutorType" value="REUSE" />
<!-- 数据库超过25000秒仍未响应则超时 -->
<setting name="defaultStatementTimeout" value="25000" />
<!-- 打印查询语句 -->
<setting name="logImpl" value="STDOUT_LOGGING" />
</settings>
<typeAliases>
<!-- All Entity -->
</typeAliases>
</configuration>
同样的方式编写db2的mapper和xml信息,这里就不在赘述了。
全部配置完成,项目结构如图所示:
5.测试
至此多数据源的配置全部完成,为了方便查看效果,我们编写一个controller直接调用mapper,这里就不在写service了。
1)TestConroller.java
@RestController
public class TestController {
@Autowired
public UserMapper_db1 db1;
@Autowired
public UserMapper_db2 db2;
@RequestMapping("/testdb1")
public User testdb1() {
return db1.findUser();
}
@RequestMapping("/testdb2")
public User testdb2() {
return db2.findUser();
}
}
2)启动发现确实配置了两个数据源
3)测试
测试db1结果:
测试db2结果:
可以发现,结果和我们预期的一样,不同包下面的mapper查询的数据库不一样。