• springBoot多数据源配置,如mysql、hive,使用druid连接池


    总共需要以下几个类:

    package com.config.datasource;

    import com.alibaba.druid.pool.DruidDataSource;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Primary;

    import javax.sql.DataSource;
    import java.util.HashMap;
    import java.util.Map;

    /**
    * @date 2019/10/11 15:27
    * @description
    */
    @Slf4j
    @Configuration
    public class DataSourceConfig {

    @Value("${spring.datasource.driver-class-name}")
    private String driverClassName;
    @Value("${spring.datasource.url}")
    private String url;
    @Value("${spring.datasource.username}")
    private String userName;
    @Value("${spring.datasource.password}")
    private String password;

    @Value("${spring.datasource.hive.driver-class-name}")
    private String hiveDriverClassName;
    @Value("${spring.datasource.hive.url}")
    private String hiveJdbcUrl;
    @Value("${spring.datasource.hive.username}")
    private String hiveUsername;
    @Value("${spring.datasource.hive.password}")
    private String hivePassword;

    @Bean(name = "datasourceMysql")
    public DataSource getDataSourceMysql() {
    DruidDataSource dataSource = new DruidDataSource();
    dataSource.setDriverClassName(driverClassName);
    dataSource.setUrl(url);
    dataSource.setUsername(userName);
    dataSource.setPassword(password);
    log.info("------------datasourceMysql dataSource.getUrl(): {}", dataSource.getUrl());
    return dataSource;
    }

    @Bean(name = "datasourceHive")
    public DataSource getDataSourceHive() {
    DruidDataSource dataSource = new DruidDataSource();
    dataSource.setDriverClassName(hiveDriverClassName);
    dataSource.setUrl(hiveJdbcUrl);
    dataSource.setUsername(hiveUsername);
    dataSource.setPassword(hivePassword);
    dataSource.setTestWhileIdle(true);
    log.info("------------------------datasourceHive dataSource.getUrl(): {}", dataSource.getUrl());
    return dataSource;
    }

    /**
    * 动态数据源: 通过AOP在不同数据源之间动态切换
    *
    * @return
    */
    @Primary
    @Bean(name = "dynamicDataSource")
    public DataSource dynamicDataSource() {
    DynamicDataSource dynamicDataSource = new DynamicDataSource();
    // 默认数据源
    dynamicDataSource.setDefaultTargetDataSource(getDataSourceMysql());
    // 配置多数据源
    Map<Object, Object> dsMap = new HashMap();
    dsMap.put(DynamicDataSource.DS_MYSQL, getDataSourceMysql());
    dsMap.put(DynamicDataSource.DS_HIVE, getDataSourceHive());
    dynamicDataSource.setTargetDataSources(dsMap);
    return dynamicDataSource;
    }

    }
    2

    package content.config.datasource;

    import lombok.extern.slf4j.Slf4j;
    import org.springframework.util.ObjectUtils;

    /**
    * @date 2019/10/11 15:55
    * @description
    */
    @Slf4j
    public class DataSourceContextHolder {
    /**
    * 默认数据源
    */
    public static final String DEFAULT_DS = "mysql";

    private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();

    // 设置数据源名
    public static void setDB(String dbType) {
    log.info("setDB -> dbType = [{}]", dbType);
    CONTEXT_HOLDER.set(dbType);
    }

    // 获取数据源名
    public static String getDB() {
    return ObjectUtils.isEmpty(CONTEXT_HOLDER.get()) ? DEFAULT_DS : CONTEXT_HOLDER.get();

    }

    /**
    * 清除数据源名
    */
    public static void clearDB() {
    CONTEXT_HOLDER.remove();
    }
    }
    3

    package content.config.datasource;

    import lombok.extern.slf4j.Slf4j;
    import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

    /**
    * @date 2019/10/11 15:53
    * @description
    */
    @Slf4j
    public class DynamicDataSource extends AbstractRoutingDataSource {

    public static final String DS_MYSQL = "mysql";

    public static final String DS_HIVE = "hive";


    @Override
    protected Object determineCurrentLookupKey() {
    log.info("the dynamic DataSource is: {}", DataSourceContextHolder.getDB());
    return DataSourceContextHolder.getDB();
    }
    }
    4

    package content.config.datasource;

    import lombok.extern.slf4j.Slf4j;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.springframework.stereotype.Component;

    import javax.annotation.Resource;

    /**
    * @date 2019/10/11 15:59
    * @description
    */
    @Slf4j
    @Component
    @Aspect
    public class DynamicDataSourceAspect {

    @Resource
    private SqlSessionFactory sqlSessionFactory;

    /**
    * @param point
    */
    @Before("execution(* unified.content.dao.hive.*.*(..))")
    public void beforeSwitchDS(JoinPoint point) {
    // Object target = point.getTarget();
    DataSourceContextHolder.setDB(DynamicDataSource.DS_HIVE);
    sqlSessionFactory.getConfiguration().setUseColumnLabel(Boolean.FALSE);
    }

    /**
    * @param point
    */
    @After("execution(* unified.content.dao.*.*.*(..))")
    public void afterSwitchDS(JoinPoint point) {
    DataSourceContextHolder.clearDB();
    sqlSessionFactory.getConfiguration().setUseColumnLabel(Boolean.TRUE);
    }

    }
    注意,springboot启动入口要加上注解:

    @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
    否则会有循环依赖报错。

    ***************************
    APPLICATION FAILED TO START
    ***************************

    Description:

    The dependencies of some of the beans in the application context form a cycle:

    dynamicDataSourceAspect

    sqlSessionFactory defined in class path resource [org/mybatis/spring/boot/autoconfigure/MybatisAutoConfiguration.class]
    ┌─────┐
    | dynamicDataSource defined in class path resource [unified/content/config/datasource/DataSourceConfig.class]
    ↑ ↓
    | datasourceMysql defined in class path resource [unified/content/config/datasource/DataSourceConfig.class]
    ↑ ↓
    | org.springframework.boot.autoconfigure.jdbc.DataSourceInitializerInvoker
     

    然后就可以了。

    这是mysql和hive多数据源的配置,也可以是和impala等其它数据源一起配置。

    druid配置(application-dev.properties):


    #druid连接池设置
    spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
    spring.datasource.druid.initial-size=1
    spring.datasource.druid.min-idle=3
    spring.datasource.druid.max-active=20
    spring.datasource.druid.max-wait=6000
    spring.datasource.druid.time-between-eviction-runs-millis=60000
    spring.datasource.druid.min-evictable-idle-time-millis=30000
    spring.datasource.druid.validation-query=select 1
    spring.datasource.druid.test-while-idle=true
    spring.datasource.druid.test-on-borrow=false
    spring.datasource.druid.test-on-return=false
    spring.datasource.druid.pool-prepared-statements=true
    spring.datasource.druid.max-pool-prepared-statement-per-connection-size=20
    spring.datasource.druid.connection-error-retry-attempts=0
    spring.datasource.druid.break-after-acquire-failure=true

    # mysql
    spring.datasource.driver-class-name=com.mysql.jdbc.Driver
    spring.datasource.url=jdbc:mysql://172.28.xx.xxx:3306/xxxx?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true
    spring.datasource.username=xxx
    spring.datasource.password=xxx


    #hive配置
    spring.datasource.hive.driver-class-name=org.apache.hive.jdbc.HiveDriver
    spring.datasource.hive.url=jdbc:hive2://172.16.xx.xx:xxxx/default
    spring.datasource.hive.username=hive
    spring.datasource.hive.password=xxx
     

    maven包相关依赖,见pom文件:

    <dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>${druid.version}</version>
    </dependency>

    <!-- 引入hive-jdbc -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
    <dependency>
    <groupId>org.apache.hive</groupId>
    <artifactId>hive-jdbc</artifactId>
    <version>2.3.3</version>
    <exclusions>
    <exclusion>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    </exclusion>
    <exclusion>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    </exclusion>
    <exclusion>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    </exclusion>
    <exclusion>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    </exclusion>
    </exclusions>
    </dependency>
    <!-- 引入hbase -->
    <dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-hadoop</artifactId>
    <version>${spring.hadoop.version}</version>
    <exclusions>
    <exclusion>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    </exclusion>
    <exclusion>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    </exclusion>
    <exclusion>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    </exclusion>
    </exclusions>
    </dependency>
    <dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-hadoop-hbase</artifactId>
    <version>${spring.hadoop.version}</version>
    <exclusions>
    <exclusion>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    </exclusion>
    </exclusions>
    </dependency>
    <dependency>
    <groupId>org.apache.hbase</groupId>
    <artifactId>hbase-client</artifactId>
    <version>1.3.0</version>
    <!--<version>1.3.6</version>-->
    <exclusions>
    <exclusion>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    </exclusion>
    </exclusions>
    </dependency>
    <!-- -->


    <!--mysql-->
    <dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.1</version>
    </dependency>
    <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.47</version>
    </dependency>
     

    附录:

    单独连接hive的配置可如下:

    package unified.content.config;

    import com.alibaba.druid.pool.DruidDataSource;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.jdbc.core.JdbcTemplate;

    import javax.sql.DataSource;

    /**
    *
    */
    @Configuration
    @ConfigurationProperties(prefix = "spring.datasource")
    public class HiveDruidConfig {

    @Value("hive.url")
    private String url;
    @Value("hive.username")
    private String username;
    @Value("hive.password")
    private String password;
    @Value("hive.driver-class-name")
    private String driverClassName;


    @Bean(name = "hiveDataSource")
    @Qualifier("hiveDataSource")
    public DataSource hiveDataSource() {
    DruidDataSource datasource = new DruidDataSource();
    datasource.setUrl(url);
    datasource.setUsername(username);
    datasource.setPassword(password);
    datasource.setDriverClassName(driverClassName);
    return datasource;
    }

    @Bean(name = "hiveJdbcTemplate")
    public JdbcTemplate hiveJdbcTemplate(@Qualifier("hiveDataSource") DataSource dataSource) {
    return new JdbcTemplate(dataSource);
    }
    //省略getter、setter
    }
    CRUD示例:

    package unified.content.controller;

    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.dao.DataAccessException;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;

    import javax.sql.DataSource;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;

    /**
    * 测试
    */
    @Slf4j
    @RestController
    @RequestMapping("/hive")
    public class HiveController {


    @Autowired
    @Qualifier("datasourceHive")
    private DataSource hiveDataSource;

    @Autowired
    @Qualifier("hiveJdbcTemplate")
    private JdbcTemplate hiveJdbcTemplate;

    @RequestMapping("/table/show")
    public List<String> showtables() {
    List<String> list = new ArrayList<String>();
    Statement statement = null;
    try {
    statement = hiveDataSource.getConnection().createStatement();
    String sql = "show tables";
    log.info("Running: " + sql);
    ResultSet res = statement.executeQuery(sql);

    // List<Map<String, Object>> maps = hiveJdbcTemplate.queryForList(sql);

    while (res.next()) {
    list.add(res.getString(1));
    }
    } catch (SQLException e) {
    e.printStackTrace();
    }
    return list;
    }

    /**
    * 查询Hive库中的某张数据表字段信息
    */
    @RequestMapping("/table/describe")
    public List<String> describeTable(String tableName) throws SQLException {
    List<String> list = new ArrayList<String>();
    // Statement statement = jdbcDataSource.getConnection().createStatement();
    Statement statement = hiveDataSource.getConnection().createStatement();
    String sql = "describe " + tableName;
    log.info("Running: " + sql);
    ResultSet res = statement.executeQuery(sql);
    while (res.next()) {
    list.add(res.getString(1));
    }
    return list;
    }

    /**
    * 查询指定tableName表中的数据
    */
    @RequestMapping("/table/select")
    public List<String> selectFromTable(String tableName) throws SQLException {
    // Statement statement = jdbcDataSource.getConnection().createStatement();
    Statement statement = hiveDataSource.getConnection().createStatement();
    String sql = "select * from " + tableName;
    log.info("Running: " + sql);
    ResultSet res = statement.executeQuery(sql);
    List<String> list = new ArrayList<String>();
    int count = res.getMetaData().getColumnCount();
    String str = null;
    while (res.next()) {
    str = "";
    for (int i = 1; i < count; i++) {
    str += res.getString(i) + " ";
    }
    str += res.getString(count);
    log.info(str);
    list.add(str);
    }
    return list;
    }


    /**
    * @return
    */
    @RequestMapping("/table/select2")
    public String select() {
    String sql = "select * from HIVE_TEST";
    List<Map<String, Object>> rows = hiveJdbcTemplate.queryForList(sql);
    Iterator<Map<String, Object>> it = rows.iterator();
    while (it.hasNext()) {
    Map<String, Object> row = it.next();
    System.out.println(String.format("%s\t%s", row.get("key"), row.get("value")));
    }
    return "Done";
    }


    /**
    * 示例:创建新表
    */
    @RequestMapping("/table/create")
    public String createTable() {
    StringBuffer sql = new StringBuffer("CREATE TABLE IF NOT EXISTS ");
    sql.append("user_sample");
    sql.append("(user_num BIGINT, user_name STRING, user_gender STRING, user_age INT)");
    sql.append("ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n' "); // 定义分隔符
    sql.append("STORED AS TEXTFILE"); // 作为文本存储

    log.info("Running: " + sql);
    String result = "Create table successfully...";
    try {
    // hiveJdbcTemplate.execute(sql.toString());
    hiveJdbcTemplate.execute(sql.toString());
    } catch (DataAccessException dae) {
    result = "Create table encounter an error: " + dae.getMessage();
    log.error(result);
    }
    return result;

    }

    /**
    * 示例:将Hive服务器本地文档中的数据加载到Hive表中
    */
    @RequestMapping("/table/load")
    public String loadIntoTable() {
    String filepath = "/home/hadoop/user_sample.txt";
    String sql = "load data local inpath '" + filepath + "' into table user_sample";
    String result = "Load data into table successfully...";
    try {
    // hiveJdbcTemplate.execute(sql);
    hiveJdbcTemplate.execute(sql);
    } catch (DataAccessException dae) {
    result = "Load data into table encounter an error: " + dae.getMessage();
    log.error(result);
    }
    return result;
    }

    /**
    * 示例:向Hive表中添加数据
    */
    @RequestMapping("/table/insert")
    public String insertIntoTable() {
    String sql = "INSERT INTO TABLE user_sample(user_num,user_name,user_gender,user_age) VALUES(888,'Plum','M',32)";
    String result = "Insert into table successfully...";
    try {
    // hiveJdbcTemplate.execute(sql);
    hiveJdbcTemplate.execute(sql);
    } catch (DataAccessException dae) {
    result = "Insert into table encounter an error: " + dae.getMessage();
    log.error(result);
    }
    return result;
    }

    /**
    * 示例:删除表
    */
    @RequestMapping("/table/delete")
    public String delete(String tableName) {
    String sql = "DROP TABLE IF EXISTS " + tableName;
    String result = "Drop table successfully...";
    log.info("Running: " + sql);
    try {
    // hiveJdbcTemplate.execute(sql);
    hiveJdbcTemplate.execute(sql);
    } catch (DataAccessException dae) {
    result = "Drop table encounter an error: " + dae.getMessage();
    log.error(result);
    }
    return result;
    }


    @RequestMapping("/table/delete2")
    public String delete() {
    StringBuffer sql = new StringBuffer("DROP TABLE IF EXISTS HIVE_TEST");
    log.info(sql.toString());
    hiveJdbcTemplate.execute(sql.toString());
    return "Done";
    }


    }

    ————————————————
    版权声明:本文为CSDN博主「mathlpz666」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/mathlpz126/article/details/108731347

  • 相关阅读:
    I/O多路复用技术
    网络编程的异常及处理
    LINUX的signal
    网络编程小知识
    一个位压缩技巧
    加密技术[翻译]
    暴雪的hash算法[翻译]
    喜欢就好
    【PYTHON】编码是个细致活
    【Python3】POP3协议收邮件
  • 原文地址:https://www.cnblogs.com/javalinux/p/14831933.html
Copyright © 2020-2023  润新知