在我们项目访问人数比较多,数据量比较大的情况下,我们可能需要使用多数据源的情况,将一部分数据放到另一个数据库中,比如数据库主从同步,我们项目可以写主库,读从库,降低单个数据库的压力,提高程序的性能。接下来简单搭建一下springboot+mybatis的多数据环境。
目的
在同一个项目中集成两个数据源,可以通过程序控制指定访问的数据库。
环境
框架:springboot+mybatis
数据库:mysql
连接池:Druid
搭建步骤
1、springboot+mybatis项目
项目结构如下图
pom.xml
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.5.RELEASE</version></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 数据库操作 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.4</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.16</version></dependency></dependencies>
application.yml
###服务启动端口号server:port: 80spring:#duriddatasource:one:type: com.alibaba.druid.pool.DruidDataSourceurl: jdbc:mysql://192.168.157.6:3306/test?useSSL=false#开发环境username: rootpassword: 123456driverClassName: com.mysql.jdbc.Driver#连接池的配置信息initialSize: 5minIdle: 5maxActive: 20maxWait: 60000timeBetweenEvictionRunsMillis: 60000minEvictableIdleTimeMillis: 300000validationQuery: SELECT 1 FROM DUALtestWhileIdle: truetestOnBorrow: falsetestOnReturn: falsepoolPreparedStatements: truemaxPoolPreparedStatementPerConnectionSize: 20two:type: com.alibaba.druid.pool.DruidDataSourceurl: jdbc:mysql://192.168.157.7:3306/test?useSSL=falseusername: rootpassword: 123456driverClassName: com.mysql.jdbc.Driver#连接池的配置信息initialSize: 5minIdle: 5maxActive: 20maxWait: 60000timeBetweenEvictionRunsMillis: 60000minEvictableIdleTimeMillis: 300000validationQuery: SELECT 1 FROM DUALtestWhileIdle: truetestOnBorrow: falsetestOnReturn: falsepoolPreparedStatements: truemaxPoolPreparedStatementPerConnectionSize: 20
上面是用one和two来区分两个数据源,一个是192.168.157.6服务器一个是192.168.157.7服务器
2、DataSourcesConfig.java
spring容器中建立DataSource
@Configurationpublic class DataSourcesConfig {@Bean@ConfigurationProperties(prefix = "spring.datasource.one")DataSource dsOne(){return DruidDataSourceBuilder.create().build();}@Bean@ConfigurationProperties(prefix = "spring.datasource.two")DataSource dsTwo(){return DruidDataSourceBuilder.create().build();}}
3、MyBatisConfigOne.java
@Configuration@MapperScan(basePackages = "com.suibibk.mapper.mapper1",sqlSessionFactoryRef = "sqlSessionFactory1",sqlSessionTemplateRef = "sqlSessionTemplate1")public class MyBatisConfigOne {@ResourceDataSource dsOne;@BeanSqlSessionFactory sqlSessionFactory1()throws Exception {SqlSessionFactoryBean bean = new SqlSessionFactoryBean();bean.setDataSource(dsOne);bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/mapper1/*.xml"));return bean.getObject();}@BeanSqlSessionTemplate sqlSessionTemplate1() throws Exception{return new SqlSessionTemplate(sqlSessionFactory1());}}
指定了扫包路径以及xml路径,当然如果是将sql直接写在mapper里面,不用xml配置文件的话可以不指定内容
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/mapper1/*.xml"));
4、MyBatisConfigTwo.java
@Configuration@MapperScan(basePackages = "com.suibibk.mapper.mapper2",sqlSessionFactoryRef = "sqlSessionFactory2",sqlSessionTemplateRef = "sqlSessionTemplate2")public class MyBatisConfigTwo {@ResourceDataSource dsTwo;@BeanSqlSessionFactory sqlSessionFactory2()throws Exception {SqlSessionFactoryBean bean = new SqlSessionFactoryBean();bean.setDataSource(dsTwo);bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/mapper2/*.xml"));return bean.getObject();}@BeanSqlSessionTemplate sqlSessionTemplate2() throws Exception{return new SqlSessionTemplate(sqlSessionFactory2());}}
5、UserMapper1.java
public interface UserMapper1 {//@Select("select * from user")List<User> getUsers();}
6、UserMapper2.java
public interface UserMapper2 {//@Select("select * from user")List<User> getUsers();}
如果在这里面写sql的话,那么MyBatisConfig就不需要指定xml位置。
7、UserMapper1.xml
<mapper namespace="com.suibibk.mapper.mapper1.UserMapper1" ><select id="getUsers" resultType="com.suibibk.entity.User">select * from user</select></mapper>
8、UserMapper2.xml
<mapper namespace="com.suibibk.mapper.mapper2.UserMapper2" ><select id="getUsers" resultType="com.suibibk.entity.User">select * from user</select></mapper>
9、service
public interface UserService {List<User> getUsers1();List<User> getUsers2();}@Servicepublic class UserServiceImpl implements UserService{@AutowiredUserMapper1 userMapper1;@AutowiredUserMapper2 userMapper2;public List<User> getUsers1() {return userMapper1.getUsers();}public List<User> getUsers2() {return userMapper2.getUsers();}}
10、controller
/*** http://localhost/test1 访问数据源1* http://localhost/test2 访问数据源2*/@Controllerpublic class TestController {@AutowiredUserService userService;@ResponseBody@RequestMapping("/test1")public String test1() {List<User> users = userService.getUsers1();return users.toString();}@ResponseBody@RequestMapping("/test2")public String test2() {List<User> users = userService.getUsers2();return users.toString();}}
11、User.java
public class User {private String name;private String passwd;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPasswd() {return passwd;}public void setPasswd(String passwd) {this.passwd = passwd;}@Overridepublic String toString() {return "User [name=" + name + ", passwd=" + passwd + "]";}}
12、启动App.java
@SpringBootApplicationpublic class App {public static void main(String[] args) {SpringApplication.run(App.class, args);}}
测试
启动后访问
http://localhost/test1http://localhost/test2
可以看到test1查询到的是192.168.157.6服务器数据库的数据,test2查询到的是192.168.157.7服务器的数据
