springboot-mybatis—多数据源
来源:互联网 发布:淘宝店铺免费一键复制 编辑:程序博客网 时间:2024/06/07 04:56
工作老系统添加新的功能 需要调用其他数据库的资源,应用多数据源,老大只给一晚上解决,哎,总算是磨出来(看了很多好的博客),我也记录一篇,也给后人方便。 原理简单说明,详细请看代码分析。 1. 配置多个数据源 =》 每个数据源一个key。 2. 将多个数据源注入到DynmicDataSource(自己定义,必须实现AbstractRoutingDataSource)。 3. 设置默认数据源,其他由业务手动获取key后动态注入达到切换数据源的效果。 4. 授人以鱼不如授人以渔,我看了很多同学博客,懂了原理才能进步,希望不要以完成任务为目的,多多分析,其它同学还可以有aop实现动态注入数据源,在这里我时间紧迫,且工作需求不大,在这里就不再分析aop情况。
1.pom 文件
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.mybatis.datasources</groupId> <artifactId>spring-boot-datasources</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>spring-boot-datasources</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.2.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- 连接池 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.29</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build></project>
2.application.properties 配置 主从数据源基本数据
#主数据源primary.datasource.driverClassName = com.mysql.jdbc.Driverprimary.datasource.url = jdbc:mysql://localhost:3306/mybatisprimary.datasource.username = rootprimary.datasource.password = root#从数据源customer.datasource.driverClassName = com.mysql.jdbc.Drivercustomer.datasource.url = jdbc:mysql://localhost:3306/lucenecustomer.datasource.username = rootcustomer.datasource.password = root
3.DataSourceType (数据源key)
public enum DataSourceType { mybatis , lucene //(用数据库名方便记忆)}
4.DynamicDataSource (动态数据源 )
package com.mybatis.datasources.config;import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;/** * Created by guoyao on 2017/4/18. */public class DynamicDataSource extends AbstractRoutingDataSource { private static final ThreadLocal<DataSourceType> contextHolder=new ThreadLocal<>(); /** * 动态数据源(继承AbstractRoutingDataSource) */ @Override //父类方法 protected Object determineCurrentLookupKey() { return getDatabaseType(); } public static void setDatabaseType(DataSourceType type) { contextHolder.set(type); } public static DataSourceType getDatabaseType() { return contextHolder.get(); }}
5.动态数据源源码分析 AbstractRoutingDataSource
protected DataSource determineTargetDataSource() { Assert.notNull(this.resolvedDataSources, "DataSource router not initialized"); //获取lookupkey Object lookupKey = this.determineCurrentLookupKey(); //由lookupkey 获取数据源 (动态指定的关键) DataSource dataSource = (DataSource)this.resolvedDataSources.get(lookupKey); if(dataSource == null && (this.lenientFallback || lookupKey == null)) { dataSource = this.resolvedDefaultDataSource; } if(dataSource == null) { throw new IllegalStateException("Cannot determine target DataSource for lookup key [" + lookupKey + "]"); } else { return dataSource; } } //指定lookupkey protected abstract Object determineCurrentLookupKey();
6.mybatis-config 配置类编写
package com.mybatis.datasources.config;import com.alibaba.druid.pool.DruidDataSourceFactory;import org.apache.ibatis.session.SqlSessionFactory;import org.mybatis.spring.SqlSessionFactoryBean;import org.mybatis.spring.annotation.MapperScan;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Primary;import org.springframework.jdbc.datasource.DataSourceTransactionManager;import javax.sql.DataSource;import java.util.HashMap;import java.util.Map;import java.util.Properties;/** * Created by guoyao on 2017/4/18. */@Configuration@MapperScan("com.mybatis.datasources.mapper")public class MyBatisConfig { @Autowired //采用java配置类读取配置(application.properties) private PrimaryDataSourceProperty primaryDataSourceProperty; @Autowired //采用java配置类读取配置(application.properties) private CustomerDataSourceProperty customerDataSourceProperty; /** * 创建数据源(方法名即实例化对象名,可以由对象名指定注入@Qualifier ) */ @Bean public DataSource dbDataSource1() throws Exception { Properties props=new Properties(); props.put("driverClassName", primaryDataSourceProperty.getDriverClassName()); props.put("url", primaryDataSourceProperty.getUrl()); props.put("username", primaryDataSourceProperty.getUsername()); props.put("password", primaryDataSourceProperty.getPassword()); // 连接池 创建数据源 可用 DataSourceBuilder 非连接池方式 return DruidDataSourceFactory.createDataSource(props); } @Bean public DataSource dbDataSource2() throws Exception { Properties props=new Properties(); props.put("driverClassName", customerDataSourceProperty.getDriverClassName()); props.put("url", customerDataSourceProperty.getUrl()); props.put("username", customerDataSourceProperty.getUsername()); props.put("password", customerDataSourceProperty.getPassword()); return DruidDataSourceFactory.createDataSource(props); } /** * @Primary 该注解表示在同一个接口有多个实现类可以注入的时候,默认选择哪一个,而不是让@autowire注解报错 * @Qualifier 根据名称进行注入,通常是在具有相同的多个类型的实例的一个注入(例如有多个DataSource类型的实例) */ @Bean @Primary public DynamicDataSource ds(@Qualifier("dbDataSource1") DataSource dbDataSource1, @Qualifier("dbDataSource2") DataSource dbDataSource2) { Map<Object, Object> targetDataSources=new HashMap<>(); targetDataSources.put(DataSourceType.mybatis, dbDataSource1); targetDataSources.put(DataSourceType.lucene, dbDataSource2); DynamicDataSource dataSource=new DynamicDataSource(); // 该方法是AbstractRoutingDataSource的方法 // 即源码分析中map resolvedDataSources 属性由lookupkey获取 dataSource.setTargetDataSources(targetDataSources); dataSource.setDefaultTargetDataSource(dbDataSource1);// 默认的datasource设置为dbDataSource1 return dataSource; } /** * 根据数据源创建SqlSessionFactory */ @Bean public SqlSessionFactory sqlSessionFactory(DynamicDataSource ds) throws Exception { SqlSessionFactoryBean fb=new SqlSessionFactoryBean(); fb.setDataSource(ds);// 指定数据源 return fb.getObject(); } /** * 配置事务管理器 */ @Bean public DataSourceTransactionManager transactionManager(DynamicDataSource ds) throws Exception { return new DataSourceTransactionManager(ds); }}
7.Application ***一定要关闭datasource 自动配置
package com.mybatis.datasources;import com.mybatis.datasources.config.CustomerDataSourceProperty;import com.mybatis.datasources.config.PrimaryDataSourceProperty;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;import org.springframework.boot.context.properties.EnableConfigurationProperties;@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) //关闭datasource的自动注入@EnableConfigurationProperties({CustomerDataSourceProperty.class, PrimaryDataSourceProperty.class}) //注入配置文件public class SpringBootDatasourcesApplication { public static void main(String[] args) { SpringApplication.run(SpringBootDatasourcesApplication.class, args); }}
8.测试
package com.mybatis.datasources.mapper;import com.mybatis.datasources.dataobject.Book;import org.apache.ibatis.annotations.Mapper;import java.util.List;/** * Created by guoyao on 2017/4/18. */@Mapperpublic interface BookMapper { //@Select("select * from book ") //@ResultType(value = Book.class) List<Book> findAll();}@Mapperpublic interface UserMapper { //@Select("select * from user ") //@ResultType(value = User.class) List<User> findAll();}@Service("bookService")public class BookServiceImpl implements BookService { @Autowired private BookMapper bookDao ; @Override public List<Book> findAll() { //指定数据源 即lookupkey DynamicDataSource.setDatabaseType(DataSourceType.lucene); return bookDao.findAll(); }}@Service("userService")public class UserServiceImpl implements UserService { @Autowired private UserMapper userDao ; @Override public List<User> findAll() { return userDao.findAll(); }}/** * Created by guoyao on 2017/4/18. */@RestControllerpublic class TestController { @Autowired private UserService userService; @Autowired private BookService bookService; @RequestMapping("/getUser") public List<User> getUser() { return userService.findAll(); } @RequestMapping("/getBook") public List<Book> getBook() { return bookService.findAll(); }}
2 0
- springboot-mybatis—多数据源
- springboot + mybatis + 多数据源
- SpringBoot+Mybatis多数据源
- springboot + mybatis + 多数据源
- SpringBoot、MyBatis配置多数据源
- springboot+mybatis配置多数据源
- springboot多数据源(mybatis)
- Springboot MyBatis多数据源切换
- Springboot配置Mybatis多数据源
- SpringBoot整合Mybatis多数据源
- springBoot+mybatis多数据源的配置
- Springboot MyBatis多数据源切换
- SpringBoot下配置Mybatis多数据源
- SpringBoot整合Mybatis多数据源
- springboot-druid-mybatis多数据源使用
- springboot+mybatis配置多数据源
- springboot+mybatis多数据源配置
- SpringBoot+MyBatis+Oracle+多数据源
- KMP算法
- mysql:command not found问题解决
- Python 将json格式文件转存为RDF格式文件
- POJ 3468 A Simple Problem with Integers(线段树)
- maven错误处理
- springboot-mybatis—多数据源
- google浏览器提示https不是安全链接
- C# 验证码生成类
- linux下tar.gz、tar、bz2、zip等解压缩、压缩命令小结
- 逻辑卷管理
- Vue项目源码分析系列一
- junit能否启动web项目设置的web listener?
- Condition-线程通信更高效的方式
- 连续向文件中写入java对象后,读取报错