在我们项目访问人数比较多,数据量比较大的情况下,我们可能需要使用多数据源的情况,将一部分数据放到另一个数据库中,比如数据库主从同步,我们项目可以写主库,读从库,降低单个数据库的压力,提高程序的性能。接下来简单搭建一下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: 80
spring:
#durid
datasource:
one:
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://192.168.157.6:3306/test?useSSL=false
#开发环境
username: root
password: 123456
driverClassName: com.mysql.jdbc.Driver
#连接池的配置信息
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
two:
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://192.168.157.7:3306/test?useSSL=false
username: root
password: 123456
driverClassName: com.mysql.jdbc.Driver
#连接池的配置信息
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
上面是用one和two来区分两个数据源,一个是192.168.157.6服务器一个是192.168.157.7服务器
2、DataSourcesConfig.java
spring容器中建立DataSource
@Configuration
public 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 {
@Resource
DataSource dsOne;
@Bean
SqlSessionFactory sqlSessionFactory1()throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dsOne);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().
getResources("classpath:mapper/mapper1/*.xml"));
return bean.getObject();
}
@Bean
SqlSessionTemplate 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 {
@Resource
DataSource dsTwo;
@Bean
SqlSessionFactory sqlSessionFactory2()throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dsTwo);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().
getResources("classpath:mapper/mapper2/*.xml"));
return bean.getObject();
}
@Bean
SqlSessionTemplate 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();
}
@Service
public class UserServiceImpl implements UserService{
@Autowired
UserMapper1 userMapper1;
@Autowired
UserMapper2 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
*/
@Controller
public class TestController {
@Autowired
UserService 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;
}
@Override
public String toString() {
return "User [name=" + name + ", passwd=" + passwd + "]";
}
}
12、启动App.java
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
测试
启动后访问
http://localhost/test1
http://localhost/test2
可以看到test1查询到的是192.168.157.6服务器数据库的数据,test2查询到的是192.168.157.7服务器的数据