spring boot mybatis多数据源解决方案
在我们的项目中不免会遇到需要在一个项目中使用多个数据源的问题,像我在得到一个任务将用户的聊天记录进行迁移的时候,就是用到了三个数据源,当时使用的AOP的编程方式根据访问的方法的不同进行动态的切换数据源,觉得性能不太好,先在又新用到了一种使用方式,觉得不错,记录下来。
介绍一下DEMO项目,使用的spring boot集成mybatis,mybatis查询数据库是基于注解形式查询的,目的查询两个数据库test1和test2的用户信息,并在控制台打印。
1.pom文件
<dependencies> <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>2.1.1</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> <version>5.1.27</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <build> <resources> <resource> <directory>src/main/java</directory> <includes> <include> **/*.xml </include> </includes> </resource> <resource> <directory>src/resources</directory> </resource> </resources> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
其中添加了alibaba的druid的数据源代替了spring boot默认的hikacp,注意mysql的驱动的版本号要与自己所使用的mysql的版本号保持一致,其中build模块里面的resources里面是为了防止spring boot 过滤掉src/main/java的XML文件,毕竟有的人喜欢mybatsi查询数据库的时候使用的是XML映射文件,不过我们本次使用的 是注解的形式 ,所以<resources>里面的内容在项目中没有用到。如果直接使用注解,可以忽略该内容。
2.用户类
public class User { public Integer id; public String name; public String address; @Override public String toString() { return "User{" + "id=" + id + ", name=‘" + name + ‘\‘‘ + ", address=‘" + address + ‘\‘‘ + ‘}‘; } //get set方法省略........... }
用户类没有什么好说的,就是基本的几个属性。
3.application.properties文件配置
spring.datasource.one.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.one.username=root spring.datasource.one.password=123456 spring.datasource.one.url=jdbc:mysql://localhost:3306/test1 spring.datasource.two.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.two.username=root spring.datasource.two.password=123456 spring.datasource.two.url=jdbc:mysql://localhost:3306/test2
这里主要配置了两个数据库的访问属性,注意两个的区别为one何two的前缀不同,方便在下面使用spring boot的类安全属性的方式创建不同的数据源。
4.根据不同的前缀创建不同的数据源
@Configuration public class DataSourceConfig { @Bean @ConfigurationProperties(prefix = "spring.datasource.one") public DataSource dsOne(){ return DruidDataSourceBuilder.create().build(); } @Bean @ConfigurationProperties(prefix = "spring.datasource.two") public DataSource dsTwo(){ return DruidDataSourceBuilder.create().build(); } }
该类位于主目录的config目录下面,使用@ConfigurationProperties注解表明对应的DataSource创建的时候使用的配置文件的内容。
5.在主目录下面分别创建mapper1和mapper2包,在对应的包下面创建对应的数据层访问接口UserMapper1和UserMapper2,内容都如下所示
@Mapper public interface UserMapper1 { @Select("select * from users") List<User> getAllUser(); }
这接口里面没有什么好说的就是一个简单的mytatis的基于注解的查询所有用户的接口。
6.在config包下面创建不同的配置类MybatisConfigOne和MybatisConfigTwo两个类分别对应去扫描mapper1和mapper2两个路径下面的dao层接口。
@Configuration @MapperScan(basePackages = "com.hopec.mybatis.mapper1",sqlSessionFactoryRef = "sqlSessionFactory1", sqlSessionTemplateRef = "sqlSessionTemplate1") public class MybatisConfigOne { @Autowired @Qualifier("dsOne") DataSource ds1; @Bean SqlSessionFactory sqlSessionFactory1(){ SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(ds1); try { return bean.getObject(); } catch (Exception e) { e.printStackTrace(); } return null; } @Bean SqlSessionTemplate sqlSessionTemplate1(){ return new SqlSessionTemplate(sqlSessionFactory1()); } }
public class MybatisConfigTwo { @Autowired @Qualifier("dsTwo") DataSource ds2; @Bean SqlSessionFactory sqlSessionFactory2(){ SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(ds2); try { return bean.getObject(); } catch (Exception e) { e.printStackTrace(); } return null; } @Bean SqlSessionTemplate sqlSessionTemplate2(){ return new SqlSessionTemplate(sqlSessionFactory2()); } }
7.测试
@SpringBootTest class MybatisApplicationTests { @Autowired UserMapper1 userMapper1; @Autowired UserMapper2 userMapper2; @Test void contextLoads() { List<User> users = userMapper1.getAllUser(); System.out.println(users); List<User> allUser = userMapper2.getAllUser(); System.out.println(allUser); } }
测试结果:
如果想使用多个数据源,就继续增加就可以了,ok,大功告成了!