最近有小伙伴咨询,现在的数据多样化,可能一部分的数据存储在A地方,一部分数据存储在B地方,这样子的话,就会涉及到同一个单一的应用业务里面去多个数据源里面进行查询。然后我去网上查了一下,像这种情况还是蛮多的,例如:医疗的系统,其他ToG的系统等。所以今天这篇文章我们实战介绍下如何在spring-boot的项目里面集成多数据源,方便不同的业务接口实现自动查询对应的数据源。这里我们还是以之前的mybatisdemo的项目进行改进
一、引入mybatis的依赖
<!-- 这是mybatis-plus依赖 --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.1.1</version> </dependency> <!-- 这是mybatis-plus的代码自动生成器 --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.1.0</version> </dependency> <!-- https://mvnrepository.com/artifact/com.alibaba/druid --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.10</version> </dependency>
二、在配置文件里面配置多数据源
spring: datasource: db1: type: com.alibaba.druid.pool.DruidDataSource driverClassName: com.mysql.jdbc.Driver jdbcUrl: jdbc:mysql://192.168.31.30:3307/test?useUnicode=true&characterEncoding=utf-8&useSSL=false username: root password: 123456 db2: type: com.alibaba.druid.pool.DruidDataSource driverClassName: com.mysql.jdbc.Driver jdbcUrl: jdbc:mysql://192.168.31.30:3308/test?useUnicode=true&characterEncoding=utf-8&useSSL=false username: root password: 123456
备注:记得这里的driverClassName和jdbcUrl的配置,在有些项目里面需要写成:driver-class-name和url即可,但是这里他需要写成driverClassName和jdbcUrl,否则读取不到配置信息。
三、为每一个datasource创建一个数据源配置
1)先创建datasource1的配置文件
package com.mybatisplus.demo.config; import javax.sql.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.jdbc.datasource.DataSourceTransactionManager; @Configuration @MapperScan(basePackages = { "com.mybatisplus.demo.mapper" }, sqlSessionFactoryRef = "db1SqlSessionFactory") public class ConfigDb01 { @Bean(name = "db1DataSource") @ConfigurationProperties(prefix = "spring.datasource.db1") @Primary public DataSource testDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "db1SqlSessionFactory") public SqlSessionFactory testSqlSessionFactory(@Qualifier("db1DataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); return bean.getObject(); } @Bean(name = "db1TransactionManager") @Primary public DataSourceTransactionManager testTransactionManager(@Qualifier("db1DataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } @Bean(name = "db1SqlSessionTemplate") @Primary public SqlSessionTemplate testSqlSessionTemplate( @Qualifier("db1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) { return new SqlSessionTemplate(sqlSessionFactory); } }
2)再创建datasource2的配置文件
package com.mybatisplus.demo.config; 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.jdbc.datasource.DataSourceTransactionManager; import javax.sql.DataSource; @Configuration @MapperScan(basePackages = { "com.mybatisplus.demo.mapper2" }, sqlSessionFactoryRef = "db2SqlSessionFactory") public class ConfigDb02 { @Bean(name = "db2DataSource") @ConfigurationProperties(prefix = "spring.datasource.db2") @Primary public DataSource testDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "db2SqlSessionFactory") public SqlSessionFactory testSqlSessionFactory(@Qualifier("db2DataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); return bean.getObject(); } @Bean(name = "db2TransactionManager") @Primary public DataSourceTransactionManager testTransactionManager(@Qualifier("db2DataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } @Bean(name = "db2SqlSessionTemplate") @Primary public SqlSessionTemplate testSqlSessionTemplate( @Qualifier("db2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) { return new SqlSessionTemplate(sqlSessionFactory); } }
在上面的配置文件里面,我们可以在maperscan里面我们填写了不同mapper包的路径,也就是说,我们需要读取哪个数据库,则把mapper文件写到对应的mapper路径下即可。
四、创建不同的sql表数据
这里我们在datasource1里面创建job1的表,在datasource2里面创建job2的表
CREATE TABLE `job1` ( `id` int(11) NOT NULL, `name` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `test`.`job1` (`id`, `name`) VALUES (1, '张三');
CREATE TABLE `job2` ( `id` bigint(20) NOT NULL, `name` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `test`.`job2` (`id`, `name`) VALUES (2, '李四');
五、编写对应的controller,service和mapper
1)controller
/** * 测试从job1的表里面查询数据 * @return */ @RequestMapping("/getJob1Info") public String getJob1Info() {// kay是字段名 value是字段值 return userService.getJob1Info(1); } /** * 测试从job2的表里面查询数据 * @return */ @RequestMapping("/getJob2Info") public String getJob2Info() {// kay是字段名 value是字段值 return userService.getJob2Info(2); }
2)service
package com.mybatisplus.demo.service.impl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.mybatisplus.demo.entity.JobEntity; import com.mybatisplus.demo.entity.User; import com.mybatisplus.demo.mapper.Job1Mapper; import com.mybatisplus.demo.mapper.UserMapper; import com.mybatisplus.demo.mapper2.Job2Mapper; import com.mybatisplus.demo.service.IUserService; /** * <p> * 服务实现类 * </p> * */ @Service public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService { @Autowired private Job1Mapper job1Mapper; @Autowired private Job2Mapper job2Mapper; @Override public String getJob1Info(Integer jobId) { return job1Mapper.get1NameByJob2Id(); } @Override public String getJob2Info(Integer jobId) { return job2Mapper.get2NameByJob2Id(); } }
3)mapper
package com.mybatisplus.demo.mapper; import org.apache.ibatis.annotations.Select; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.mybatisplus.demo.entity.JobEntity; public interface Job1Mapper extends BaseMapper<JobEntity> { @Select("select name from job1 where id = 1") public String get1NameByJob2Id(); }
package com.mybatisplus.demo.mapper2; import org.apache.ibatis.annotations.Select; public interface Job2Mapper { @Select("select name from job2 where id = 2") public String get2NameByJob2Id(); }
六、进行测试
1)测试访问获取job1的参数:http://localhost:8088/user/getJob1Info
可以看到job1的表数据被查出来了。
2)测试访问获取job2的参数:http://localhost:8088/user/getJob2Info
可以看到job2的表数据被查出来了。
到这里我们配置的两个数据源都把对应的数据查询出来了。实战成功。
最后附上完整代码下载:点击下载
发表评论