原文地址:https://blog.lanweihong.com/p…
Github:spring-boot-mybatis-multiple-data-source
增加相干依赖包
编辑 pom.xml
文件,增加相干依赖:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.8</version>
<relativePath/>
</parent>
<properties>
<mysql.driver.version>8.0.16</mysql.driver.version>
<mybatis.spring.boot.version>1.3.2</mybatis.spring.boot.version>
<druid.version>1.1.10</druid.version>
<tk.mybatis.version>2.1.5</tk.mybatis.version>
<lombok.version>1.16.18</lombok.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.spring.boot.version}</version>
</dependency>
<!-- mysql driver -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.driver.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>${tk.mybatis.version}</version>
</dependency>
</dependencies>
配置 application.yml
文件
在配置文件 application.yml
中配置数据源:
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
username: root
password: Aa123456.
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
initial-size: 5
max-active: 50
max-wait: 60000
min-idle: 5
# 配置 book 数据源,可自定义
book:
# type: com.alibaba.druid.pool.DruidDataSource
# driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/db01?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai
# username: root
# password: 1
# 配置 user 数据源
user:
url: jdbc:mysql://localhost:3306/db02?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai
# 重新配置明码,未配置则默认应用以上配置的
username: root
password: 1
手动配置数据源
主数据源配置
创立配置类 BookDataSourceConfig
,配置类须要对 DataSource
、DataSourceTransactionManager
、SqlSessionFactory
、SqlSessionTemplate
四个数据项进行配置。当零碎中存在多个数据源时,必须有一个数据源为主数据源,应用 @Primary
注解润饰。
BookDataSourceConfig
配置类:
@Configuration
// 通过在 `@MapperScan` 注解中配置 `basePackages` 和 `sqlSessionTemplateRef` 来实现主动切换数据源
@MapperScan(basePackages = "com.lanweihong.dao.book",
sqlSessionFactoryRef = "bookSqlSessionFactory", sqlSessionTemplateRef = "bookSqlSessionTemplate")
public class BookDataSourceConfig {
public static final String MAPPER_LOCATION = "classpath:mapper/book/*.xml";
/**
* 主数据源
* 阐明:@Primary 如果有多个同类的 Bean,该 Bean 优先思考,多数据源时必须配置一个主数据源,用该注解标记
* @return
*/
@Primary
@Bean("bookDataSource")
@ConfigurationProperties("spring.datasource.druid.book")
public DataSource bookDataSource(){return DruidDataSourceBuilder.create().build();}
@Primary
@Bean("bookTransactionManager")
public DataSourceTransactionManager bookTransactionManager() {return new DataSourceTransactionManager(bookDataSource());
}
@Primary
@Bean("bookSqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(@Qualifier("bookDataSource") DataSource dataSource) throws Exception {SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCATION));
return sqlSessionFactoryBean.getObject();}
@Primary
@Bean("bookSqlSessionTemplate")
public SqlSessionTemplate sqlSessionTemplate(@Qualifier("bookDataSource") DataSource dataSource) throws Exception {return new SqlSessionTemplate(sqlSessionFactory(dataSource));
}
}
Mybatis 是通过配置的扫描包和对应的 sqlSessionTemplate
来主动切换数据源,即通过在 @MapperScan
注解中配置 basePackages
和 sqlSessionTemplateRef
:
@MapperScan(basePackages = "com.lanweihong.dao.book",
sqlSessionFactoryRef = "bookSqlSessionFactory", sqlSessionTemplateRef = "bookSqlSessionTemplate")
配置第二个数据源
编写配置类 UserDataSourceConfig
:
@Configuration
@MapperScan(basePackages = "com.lanweihong.dao.user", sqlSessionTemplateRef = "userSqlSessionTemplate")
public class UserDataSourceConfig {
public static final String MAPPER_LOCATION = "classpath:mapper/user/*.xml";
/**
* user 数据源
* @return
*/
@Bean("userDataSource")
@ConfigurationProperties("spring.datasource.druid.user")
public DataSource userDataSource(){return DruidDataSourceBuilder.create().build();}
@Bean("userTransactionManager")
public DataSourceTransactionManager userTransactionManager() {return new DataSourceTransactionManager(userDataSource());
}
@Bean("userSqlSessionFactory")
public SqlSessionFactory userSqlSessionFactory(@Qualifier("userDataSource") DataSource dataSource) throws Exception {SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCATION));
return sqlSessionFactoryBean.getObject();}
@Bean("userSqlSessionTemplate")
public SqlSessionTemplate userSqlSessionTemplate(@Qualifier("userDataSource") DataSource dataSource) throws Exception {return new SqlSessionTemplate(userSqlSessionFactory(dataSource));
}
}
至此,不同数据源的配置已实现,接下来应用了。
应用
按平时失常写和应用 DAO
和 Service
,Spring 会依据数据源配置的映射主动切换相应的数据源,不须要在 Service 中指定,间接应用即可。
以下 DAO/Mapper/Service/Controller
代码为示例代码,仅列出局部代码,残缺代码请看:https://github.com/lanweihong…
IBookDao
:
public interface IBookDao extends BaseMapper<BookDO> {BookDO getByBookName(@Param("bookName") String bookName);
}
BookMapper.xml
:
<?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.lanweihong.dao.book.IBookDao">
<resultMap id="BaseResultMap" type="com.lanweihong.entity.BookDO">
<id column="id" jdbcType="BIGINT" property="id" />
<result column="version" jdbcType="INTEGER" property="version" />
<result column="book_name" jdbcType="VARCHAR" property="bookName" />
<result column="status" jdbcType="TINYINT" property="status" />
<result column="add_time" jdbcType="TIMESTAMP" property="addTime" />
</resultMap>
<sql id="BaseColumnList">
id, version, book_name, status, add_time
</sql>
<select id="getByBookName" resultMap="BaseResultMap">
SELECT <include refid="BaseColumnList" /> FROM book WHERE book_name = #{bookName}
</select>
</mapper>
Service
:
@Service("bookService")
public class BookServiceImpl implements IBookService {
private final IBookDao bookDao;
@Autowired
public BookServiceImpl(IBookDao bookDao) {this.bookDao = bookDao;}
@Override
public List<BookDO> listAll() {return bookDao.selectAll();
}
@Override
public BookDO getByBookName(String bookName) {return bookDao.getByBookName(bookName);
}
}
Controller
:
@RestController
@RequestMapping("/api/v1/")
public class MainController {
private final IUserService userService;
private final IBookService bookService;
@Autowired
public MainController(IUserService userService, IBookService bookService) {
this.userService = userService;
this.bookService = bookService;
}
@GetMapping("/books")
public Map<String, Object> queryBooks(@RequestParam(value = "name", required = false) String bookName) {List<BookDO> books = new ArrayList<>();
if (StringUtil.isEmpty(bookName)) {books = this.bookService.listAll();
} else {BookDO book = bookService.getByBookName(bookName);
books.add(book);
}
Map<String, Object> result = new HashMap<>(1);
result.put("data", books);
return result;
}
@GetMapping("/users")
public Map<String, Object> queryUsers(@RequestParam(value = "name", required = false) String userName) {List<UserDO> users = new ArrayList<>();
if (StringUtil.isEmpty(userName)) {users = this.userService.listAll();
} else {UserDO user = userService.getByUserName(userName);
users.add(user);
}
Map<String, Object> result = new HashMap<>(1);
result.put("data", users);
return result;
}
}
测试
启动利用,在浏览器中拜访 http://127.0.0.1:8015/api/v1/users
及 http://127.0.0.1:8015/api/v1/books
测试;
我的项目构造
我的项目构造如下图:
代码已上传至 Github:spring-boot-mybatis-multiple-data-source
参考文档
- https://blog.csdn.net/acquain…