原文地址: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...