唯爱spring-boot 踩坑

spring-boot配置HikariCP多数据源

2017-07-13  本文已影响1733人  aef5bc56a01e

写在最前面

此文章讲述了多数据源配置,不太适用于主从数据库的配置

前言

之前的项目用到了多数据源,于是在网上搜了一些博客,发现照着写是可以,但测试的时候发现两个数据源却是同一个(或者是报错),经过调试,才发现是因为HikariCP。网上大多博客写的应该都是用的默认的tomcat-jdbc的连接池, (程序员DD的多数据源配置);也有用Druid 的(Mybatis+Druid多数据源),毕竟是阿里搞的,所以国内用的应该挺多。本文将介绍HikariCp的多数据源配置

上面的tomcat-jdbc的多数据源本人尝试配置过,是好使的;至于druid的,没尝试过,大家可以自行 调试哈

HikariCP

HikariCP是什么?是一个数据库连接池(并不是你们想的某岛国动作影星╭(╯^╰)╮)。据说是现阶段最快的了(反正我是信了)。官网地址http://brettwooldridge.github.io/HikariCP/

1. 启用HikariCP

  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
    <exclusions>
      <!--去掉默认的tomcat-jdbc的依赖-->
    <exclusion>
      <groupId>org.apache.tomcat</groupId>
      <artifactId>tomcat-jdbc</artifactId>
    </exclusion>
    </exclusions>
  </dependency>

  <dependency>
    <groupId>com.zaxxer</groupId>
    <artifactId>HikariCP</artifactId>
  </dependency>

2. 配置数据源

spring:
  datasource:
    url: jdbc:mysql://192.168.2.200:3306/union1?useUnicode=true&characterEncoding=GBK
    username: qiji
    password: qiji,123
    driver-class-name: com.mysql.jdbc.Driver

    hikari:
      connection-test-query: SELECT 1 FROM DUAL
      minimum-idle: 1
      maximum-pool-size: 5
      pool-name: bosPoolName
      max-lifetime: 1800000

    secondary:
      url: jdbc:mysql://192.168.2.200:3306/b2c?useUnicode=true&characterEncoding=GBK
      username: qiji
      password: qiji,123
      driver-class-name: com.mysql.jdbc.Driver

      hikari:
        connection-test-query: SELECT 1 FROM DUAL
        minimum-idle: 1
        maximum-pool-size: 5
        pool-name: bosPoolName
        max-lifetime: 1800000

关于配置的意思不过多解释了

3. DataSourceConfig代码

PrimaryDataSourceConfig.java

import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
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
public class PrimaryDataSourceConfig extends DataSourceAutoConfiguration{
    @Bean(name = "dataSource")
    @Primary
    @ConfigurationProperties(prefix="spring.datasource.hikari")
    public DataSource dataSource(DataSourceProperties properties){
        return DataSourceBuilder.create(properties.getClassLoader()).type(HikariDataSource.class)
                        .driverClassName(properties.determineDriverClassName())
                        .url(properties.determineUrl()).username(properties.determineUsername()).password(properties.determinePassword()).build();
    }

 @Bean
@Primary
  public JdbcTemplate jdbcTemplate(
    @Qualifier("dataSource") DataSource dataSource){
    return new JdbcTemplate(dataSource);
  }
}

SecondaryDataSourceConfig.java

package com.oqiji.union.dsconfig;

import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
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;

/**
 * Created by yangyang on 16/11/23.
 */
@Configuration
@AutoConfigureAfter({DataSourceAutoConfiguration.class})
public class VipDataSourceConfig {

  @Bean(name = "dataSourceSec")
  @ConfigurationProperties(prefix="spring.datasource.secondary.hikari")
  public DataSource secondaryDataSource(DataSourceProperties properties){
    return DataSourceBuilder.create(properties.getClassLoader()).type(HikariDataSource.class)
            .driverClassName(properties.determineDriverClassName())
            .url(properties.determineUrl()).username(properties.determineUsername()).password(properties.determinePassword()).build();
  }


  @Bean(name = "jdbcTemplateSec")
  public JdbcTemplate secondaryJdbcTemplate(
    @Qualifier("dataSourceSec") DataSource dataSource){
    return new JdbcTemplate(dataSource);
  }
}

此时配置的两个数据源已经可以使用了

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

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

4. JPA及事务配置

不同数据源对应的Model类和dao应放在不同的包下,以便JPA扫描配置

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;

import javax.persistence.EntityManager;
import javax.sql.DataSource;
import java.util.Map;

/**
 * Created by yangyang on 16/11/23.
 */

@Configuration
@EnableJpaRepositories(
                basePackages = {"com.oqiji.vs.auth.dao",
                                "com.oqiji.ud"})//设置dao(repo)所在位置
@Import({PrimaryDataSourceConfig.class})
@AutoConfigureAfter({PrimaryDataSourceConfig.class})
public class PrimaryRepositoryConfig {

    @Autowired
    private JpaProperties jpaProperties;

    @Autowired
    @Qualifier("dataSource")
    private DataSource dataSource;

    @Bean(name = "entityManager")
    @Primary
    public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
        return entityManagerFactoryPrimary(builder).getObject().createEntityManager();
    }

    @Bean(name = "entityManagerFactory")
    @Primary
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary(EntityManagerFactoryBuilder builder) {
        return builder
                        .dataSource(dataSource)
                        .properties(getVendorProperties(dataSource))
                        .packages("com.oqiji.ud.bean", "com.oqiji.jcommon.domain") //设置实体类所在位置
                        .persistenceUnit("primaryPersistenceUnit")
                        .build();
    }

    private Map<String, String> getVendorProperties(DataSource dataSource) {
        return jpaProperties.getHibernateProperties(dataSource);
    }

    @Bean(name = "transactionManager")
    @Primary
    PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
    }
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;

import javax.persistence.EntityManager;
import javax.sql.DataSource;
import java.util.Map;

/**
 * Created by yangyang on 16/11/23.
 */

@Configuration
@EnableJpaRepositories(basePackages = {"com.oqiji.sec"})//设置dao(repo)所在位置
@Import({SecondaryDataSourceConfig.class})
@AutoConfigureAfter({SecondaryDataSourceConfig.class})
public class SecondaryRepositoryConfig {

    @Autowired
    private JpaProperties jpaProperties;

    @Autowired
    @Qualifier("secDataSource")
    private DataSource dataSource;

    @Bean(name = "secEntityManager")
    public EntityManager secEntityManager(EntityManagerFactoryBuilder builder) {
        return entityManagerFactorySec(builder).getObject().createEntityManager();
    }

    @Bean(name = "secEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactorySec(EntityManagerFactoryBuilder builder) {
        return builder
                        .dataSource(secDataSource)
                        .properties(getVendorProperties(dataSource))
                        .packages("com.oqiji.sec.bean", "com.oqiji.sec.domain") //设置实体类所在位置
                        .persistenceUnit("secPersistenceUnit")
                        .build();
    }

    private Map<String, String> getVendorProperties(DataSource dataSource) {
        return jpaProperties.getHibernateProperties(dataSource);
    }

    @Bean(name = "secTransactionManager")
    PlatformTransactionManager transactionManagerSec(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(entityManagerFactorySec(builder).getObject());
    }
}
上一篇下一篇

猜你喜欢

热点阅读