场景:实际项目开发中经常会遇到需要从多个数据库中查询数据源的业务,这个时候就需要使用多数据源配置。
这里不再强带pom依赖,主要的额引用为:
<!--druid-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.18</version>
</dependency>
<!--mybaits -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.spring.boot.version}</version>
</dependency>
代码如下:
/**
* @author Shuyu.Wang
* @package:com.ganinfo.datasource
* @className:
* @description:线程安全的DatabaseType容器
* @date 2018-08-01 15:46
**/
public class DatabaseContextHolder {
private static final ThreadLocal<DatabaseType> contextHolder = new ThreadLocal<>();
public static void setDatabaseType(DatabaseType type) {
contextHolder.set(type);
}
public static DatabaseType getDatabaseType() {
return contextHolder.get();
}
}
/**
* @author Shuyu.Wang
* @package:com.ganinfo.datasource
* @className:
* @description:数据源类型枚举类
* @date 2018-08-01 15:45
**/
public enum DatabaseType {
master,slave
}
/**
* @author Shuyu.Wang
* @package:com.ganinfo.datasource
* @className:
* @description:动态数据源(需要继承AbstractRoutingDataSource)
* @date 2018-08-01 15:47
**/
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DatabaseContextHolder.getDatabaseType();
}
}
/**
* @author Shuyu.Wang
* @package:com.ganinfo.datasource
* @className:
* @description:springboot集成mybatis的基本入口 1)创建数据源(如果采用的是默认的tomcat-jdbc数据源,则不需要)
* 2)创建SqlSessionFactory 3)配置事务管理器,除非需要使用事务,否则不用配置
* @date 2018-08-01 15:49
**/
@Configuration // 该注解类似于spring配置文件
public class MyBatisConfig {
@Autowired
private Environment env;
private String MYBATIS_CONFIG = "config/mybatis.xml";
/**
* 创建数据源(数据源的名称:方法名可以取为XXXDataSource(),XXX为数据库名称,该名称也就是数据源的名称)
*/
@Bean
public DataSource masterDbDataSource() throws Exception {
Properties props = new Properties();
props.put("driverClassName", env.getProperty("spring.datasource.master.driverClassName"));
props.put("url", env.getProperty("spring.datasource.master.url"));
props.put("username", env.getProperty("spring.datasource.master.username"));
props.put("password", env.getProperty("spring.datasource.master.password"));
return DruidDataSourceFactory.createDataSource(props);
}
@Bean
public DataSource slaveDb2DataSource() throws Exception {
Properties props = new Properties();
props.put("driverClassName", env.getProperty("spring.datasource.slave.driverClassName"));
props.put("url", env.getProperty("spring.datasource.slave.url"));
props.put("username", env.getProperty("spring.datasource.slave.username"));
props.put("password", env.getProperty("spring.datasource.slave.password"));
return DruidDataSourceFactory.createDataSource(props);
}
/**
* @Primary 该注解表示在同一个接口有多个实现类可以注入的时候,默认选择哪一个,而不是让@autowire注解报错
* @Qualifier 根据名称进行注入,通常是在具有相同的多个类型的实例的一个注入(例如有多个DataSource类型的实例)
*/
@Bean
@Primary
public DynamicDataSource dataSource(@Qualifier("masterDbDataSource") DataSource masterDbDataSource, @Qualifier("slaveDb2DataSource") DataSource slaveDb2DataSource) {
Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put(DatabaseType.master, masterDbDataSource);
targetDataSources.put(DatabaseType.slave, slaveDb2DataSource);
DynamicDataSource dataSource = new DynamicDataSource();
dataSource.setTargetDataSources(targetDataSources);// 该方法是AbstractRoutingDataSource的方法
dataSource.setDefaultTargetDataSource(masterDbDataSource);// 默认的datasource设置为myTestDbDataSource
return dataSource;
}
/**
* 根据数据源创建SqlSessionFactory
*/
@Bean
public SqlSessionFactory sqlSessionFactory(@Qualifier("masterDbDataSource") DataSource masterDbDataSource, @Qualifier("slaveDb2DataSource") DataSource slaveDb2DataSource) throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
// 下边两句仅仅用于*.xml文件,如果整个持久层操作不需要使用到xml文件的话(只用注解就可以搞定),则不加
/* sqlSessionFactoryBean.setTypeAliasesPackage(env.getProperty("mybatis.typeAliasesPackage"));// 指定基包
sqlSessionFactoryBean.setMapperLocations(
new PathMatchingResourcePatternResolver().getResources(env.getProperty("mybatis.mapperLocations")));//*/
/** 设置mybatis configuration 扫描路径 */
System.out.println(env.getProperty("mybatis.configLocation"));
sqlSessionFactoryBean.setConfigLocation(new ClassPathResource(MYBATIS_CONFIG));
// 指定数据源(这个必须有,否则报错)
sqlSessionFactoryBean.setDataSource(this.dataSource(masterDbDataSource, slaveDb2DataSource));
/** 添加mapper 扫描路径 */
sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(env.getProperty("mybatis.mapperLocations")));
return sqlSessionFactoryBean.getObject();
}
/**
* 配置事务管理器
*/
@Bean
public DataSourceTransactionManager transactionManager(DynamicDataSource dataSource) throws Exception {
return new DataSourceTransactionManager(dataSource);
}
}
配置文件如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!-- map下划线自动转大写 -->
<setting name="mapUnderscoreToCamelCase" value="true" />
<!-- 打印查询语句 -->
<setting name="logImpl" value="STDOUT_LOGGING" />
<!-- 返回字段为空时null也显示该字段 -->
<setting name="callSettersOnNulls" value="true"/>
</settings>
<!-- 别名定义 -->
<typeAliases>
<!-- 批量别名定义,指定包名,mybatis自动扫描包中的po类,自动定义别名,别名是类名(首字母大写或小写都可以,一般用小写) -->
<!-- <package name="com.hotpot..pojo" /> -->
<!--<typeAlias type="com.hotpot.sys.pojo.SysUser" alias="sysUser"/> -->
<!-- 批量别名定义
指定包名,mybatis自动扫描包中的po类,自动定义别名,别名就是类名(首字母大写或小写都可以)
-->
<!--<package name="com.demo.pojo"/>-->
</typeAliases>
<plugins>
<!-- 打印sql拦截器 -->
<plugin interceptor="com.ganinfo.interceptor.MybatisInterceptor"></plugin>
</plugins>
</configuration>
测试类:
@Mapper
public interface Test {
@Select("SELECT * FROM t_user")
List<Map<String,Object>> getList();
@Select("SELECT * FROM t_base_place")
List<Map<String,Object>> getList2();
}
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestTest {
@Autowired
private com.ganinfo.datasource.mapper.Test test;
@org.junit.Test
public void getList() throws Exception {
DatabaseContextHolder.setDatabaseType(DatabaseType.master);
List<Map<String, Object>> list = test.getList();
System.out.println(GsonUtil.GsonString(list));
}
@Test
public void getList2() throws Exception {
DatabaseContextHolder.setDatabaseType(DatabaseType.slave);
List<Map<String, Object>> list = test.getList2();
System.out.println(GsonUtil.GsonString(list));
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/15845.html