Spring Boot教程十三:多数据源配置

导读:本篇文章讲解 Spring Boot教程十三:多数据源配置,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

场景:实际项目开发中经常会遇到需要从多个数据库中查询数据源的业务,这个时候就需要使用多数据源配置。

这里不再强带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

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!