平时可能有需求需要一个项目中访问多个数据源。以下是搭建多数据源的一个简单方案。
SpringBoot、MyBatis、MySQL;
下面是两个数据库school与school2,两个数据库中分别都有一个teacher表,但是数据不同,我们就来操作这两个数据库。如下
都是最基础的,如果你要用到Generator生成lombox工程,你可以看上篇文章
org.springframework.boot
spring-boot-starter-web
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.0.0
mysql
mysql-connector-java
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
我这里是application.yml格式,其它properties都是一样的。先展示一下我的文档结构,其中练习较杂,只看标注的即可。
下面是数据库配置,密码和账户非真,虚拟的。
server:
port: 8080
spring:
datasource:
test1:
driver-class-name: com.mysql.jdbc.Driver
jdbc-url: jdbc:mysql://47.113.122.168:3306/school?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=UTC
username: root
password: guaidonggua..
test2:
driver-class-name: com.mysql.jdbc.Driver
jdbc-url: jdbc:mysql://47.113.122.168:3306/school2?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=UTC
username: root
password: guaidonggua..
我这里直接使用Generator生成两次,分别是两个数据库的Mapper类和配置文件。
下面象征性地展示数据源1的代码。
```yaml
<?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.aiahtb.mapper.data1.Teacher1Mapper">
<resultMap id="BaseResultMap" type="com.aiahtb.entity.Teacher">
<id column="tid" jdbcType="INTEGER" property="tid" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="age" jdbcType="INTEGER" property="age" />
<result column="creat_time" jdbcType="TIMESTAMP" property="creatTime" />
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
</resultMap>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
delete from teacher
where tid = #{tid,jdbcType=INTEGER}
</delete>
<insert id="insert" parameterType="com.aiahtb.entity.Teacher">
insert into teacher (tid, `name`, age,
creat_time, update_time)
values (#{tid,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR}, #{age,jdbcType=INTEGER},
#{creatTime,jdbcType=TIMESTAMP}, #{updateTime,jdbcType=TIMESTAMP})
</insert>
<update id="updateByPrimaryKey" parameterType="com.aiahtb.entity.Teacher">
update teacher
set `name` = #{name,jdbcType=VARCHAR},
age = #{age,jdbcType=INTEGER},
creat_time = #{creatTime,jdbcType=TIMESTAMP},
update_time = #{updateTime,jdbcType=TIMESTAMP}
where tid = #{tid,jdbcType=INTEGER}
</update>
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
select tid, `name`, age, creat_time, update_time
from teacher
where tid = #{tid,jdbcType=INTEGER}
</select>
<select id="selectAll" resultMap="BaseResultMap">
select tid, `name`, age, creat_time, update_time
from teacher
</select>
</mapper>
public interface Teacher1Mapper {
int deleteByPrimaryKey(Integer tid);
int insert(Teacher record);
Teacher selectByPrimaryKey(Integer tid);
List<Teacher> selectAll();
int updateByPrimaryKey(Teacher record);
}
数据源1的配置,千万要注意,单词过长,仔细仔细再仔细。
package com.aiahtb.config.datasource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
/**
* @MapperScan:使用@MapperScan来扫描注册mybatis数据库接口类, basePackages:表明接口类所在的包
* sqlSessionTemplateRef:表明接口类使用的SqlSessionTemplate
* @Primary:在spring容器中,区别一个接口不同实现在属性注入时的先后顺序 详情:https://www.cnblogs.com/liaojie970/p/7885106.html
*/
@Configuration
// 配置mybatis的接口类放的地方,使用扫描,mapper类上就不用添加@Mapper注解了
@MapperScan(basePackages = "com.aiahtb.mapper.data1", sqlSessionTemplateRef = "test1SqlSessionTemplate")
public class DatasourceConfig1 {
@Bean(name = "test1DataSource")
@ConfigurationProperties(prefix = "spring.datasource.test1")
@Primary
public DataSource testDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "test1SqlSessionFactory")
@Primary
public SqlSessionFactory testSqlSessionFactory(@Qualifier("test1DataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/data1/*.xml"));
return bean.getObject();
}
@Bean(name = "test1TransactionManager")
@Primary
public DataSourceTransactionManager testTransactionManager(@Qualifier("test1DataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "test1SqlSessionTemplate")
@Primary
public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("test1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
数据源2的配置,千万要注意,单词过长,仔细仔细再仔细。
@Configuration
// 配置mybatis的接口类放的地方
@MapperScan(basePackages = "com.aiahtb.mapper.data2", sqlSessionTemplateRef = "test2SqlSessionTemplate")
public class DatasourceConfig2 {
@Bean(name = "test2DataSource")
@ConfigurationProperties(prefix = "spring.datasource.test2")
public DataSource testDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "test2SqlSessionFactory")
public SqlSessionFactory testSqlSessionFactory(@Qualifier("test2DataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/data2/*.xml"));
return bean.getObject();
}
@Bean(name = "test2TransactionManager")
public DataSourceTransactionManager testTransactionManager(@Qualifier("test2DataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "test2SqlSessionTemplate")
public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("test2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class) // 指定引导类
public class DemoApplicationTests {
private static final Logger logger = LoggerFactory.getLogger(DemoApplicationTests.class);
@Autowired
private Teacher1Mapper teacher1Mapper;
@Autowired
private Teacher2Mapper teacher2Mapper;
/**
* 测试多数据源
*/
@Test
public void moreDataSource() {
System.out.println("测试多数据源\n");
teacher1Mapper.selectAll().forEach(n -> {
System.out.println(n.toString());
});
System.out.println("\n");
teacher2Mapper.selectAll().forEach(n -> {
System.out.println(n.toString());
});
System.out.println("\n");
}
}
测试结果
[参考文献]
纯洁的微笑:http://www.ityouknow.com/springboot/2016/11/25/spring-boot-multi-mybatis.html