学习Spring Boot:(二十四)多数据源配置与使用

摘要:
文本JdbcTemplate多数据源配置需要在SpringBoot中配置多个数据库连接。当然,如何设置连接参数的键可以由您自己决定。应该注意,SpringBoot2.0中的默认连接池配置参数似乎有问题。由于默认连接池已从Tomcat更改为HikariCP,因此之前有一个参数url已更改为hikari.jdbcUrl,否则无法注册。UseSSL=false&allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8用户名:root密码:123457驱动程序类名:com.mysql.jdbc.Driver Register DataSource注册两个数据源,分别注册两个JdbcTemplates,@ConfigurationpublicclassDataSourceConfig{/**注册数据源**@return*/@ConfigurationProperties@Bean@Primary//使用相同的实例,选择publicDataSourcefirstDataSource(){returnDataSourceBuilder.create().build();}first@ConfigurationProperties@BeanpublicDataSourcesecondDataSource(){returnDataSourceBuilder.create().build();}@Bean@PrimarypublicJdbcTemplatefirstJdbcTemplate{returnnewJdbcTemplate;}@BeanpublicJdbcTemplatesecondJdbcTemplate{retornnewJdbc Template;}}测试@SpringBootTest@RunWithpublicclassTestJDBC{@AutowiredprivateJdbcTemplatejdbcTemplate;@Autowired@QualifierprivateJdbcTemplatejdbcTemplate1 ;@ Beforepublicvoid before(){jdbcTemplate.update;jdbcTemplate1。更新;}@Testpublicvoid testJDBC(){jdbcTemplate.update;jdbcTemplate1。使现代化明确肯定assertThat;明确肯定assertThat;}}源地址使用JPA来支持多个数据源配置。与使用jdbcTemplate相比,您需要设置JPA的相关参数。没有大的变化:服务器:端口:8022spring:数据源:url:jdbc:mysql://localhost:3306/learn?

前言

随着业务量增大,可能有些业务不是放在同一个数据库中,所以系统有需求使用多个数据库完成业务需求,我们需要配置多个数据源,从而进行操作不同数据库中数据。

正文

JdbcTemplate 多数据源

配置

需要在 Spring Boot 中配置多个数据库连接,当然怎么设置连接参数的 key 可以自己决定,

需要注意的是 Spring Boot 2.0 的默认连接池配置参数好像有点问题,由于默认连接池已从 Tomcat 更改为 HikariCP,以前有一个参数 url,已经改成 hikari.jdbcUrl ,不然无法注册。我下面使用的版本是 1.5.9

server:
  port: 8022
spring:
  datasource:
     url: jdbc:mysql://localhost:3306/learn?useSSL=false&allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8
     username: root
     password: 123456
     driver-class-name: com.mysql.jdbc.Driver

  second-datasource:
    url: jdbc:mysql://localhost:3306/learn1?useSSL=false&allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8
    username: root
    password: 123457
    driver-class-name: com.mysql.jdbc.Driver
注册 DataSource

注册两个数据源,分别注册两个 JdbcTemplate

@Configuration
public class DataSourceConfig {

    /**
     * 注册 data source
     *
     * @return
     */
    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean("firstDataSource")
    @Primary // 有相同实例优先选择
    public DataSource firstDataSource() {
        return DataSourceBuilder.create().build();
    }

    @ConfigurationProperties(prefix = "spring.second-datasource")
    @Bean("secondDataSource")
    public DataSource secondDataSource() {
        return DataSourceBuilder.create().build();
    }

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

    @Bean("secondJdbcTemplate")
    public JdbcTemplate secondJdbcTemplate(@Qualifier("secondDataSource") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
}
测试
@SpringBootTest
@RunWith(SpringRunner.class)
public class TestJDBC {
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    @Qualifier("secondJdbcTemplate")
    private JdbcTemplate jdbcTemplate1;

    @Before
    public void before() {
        jdbcTemplate.update("DELETE FROM employee");
        jdbcTemplate1.update("DELETE FROM employee");
    }

    @Test
    public void testJDBC() {
        jdbcTemplate.update("insert into employee(id,name,age) VALUES (1, 'wuwii', 24)");
        jdbcTemplate1.update("insert into employee(id,name,age) VALUES (1, 'kronchan', 23)");
        Assert.assertThat("wuwii", Matchers.equalTo(jdbcTemplate.queryForObject("SELECT name FROM employee WHERE id=1", String.class)));
        Assert.assertThat("kronchan", Matchers.equalTo(jdbcTemplate1.queryForObject("SELECT name FROM employee WHERE id=1", String.class)));
    }
}

源码地址

使用 JPA 支持多数据源

配置

相比使用 jdbcTemplate,需要设置下 JPA 的相关参数即可,没多大变化:

server:
  port: 8022
spring:
  datasource:
     url: jdbc:mysql://localhost:3306/learn?useSSL=false&allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8
     username: root
     password: 123456
     driver-class-name: com.mysql.jdbc.Driver

  second-datasource:
    url: jdbc:mysql://localhost:3306/learn1?useSSL=false&allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver

  jpa:
    show-sql: true
    database: mysql
    hibernate:
    # update 更新表结构
    # create 每次启动删除上次表,再创建表,会造成数据丢失
    # create-drop: 每次加载hibernate时根据model类生成表,但是sessionFactory一关闭,表就自动删除。
    # validate :每次加载hibernate时,验证创建数据库表结构,只会和数据库中的表进行比较,不会创建新表,但是会插入新值。
      ddl-auto: update
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQLDialect

首先一样的是我们要注册相应的 DataSource,还需要指定相应的数据源所对应的实体类和数据操作层 Repository的位置:
* firstDataSource

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "firstEntityManagerFactory",
        transactionManagerRef = "firstTransactionManager",
        basePackages = "com.wuwii.module.system.dao" // 设置该数据源对应 dao 层所在的位置
)
public class FirstDataSourceConfig {

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

    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean("firstDataSource")
    @Primary // 有相同实例优先选择,相同实例只能设置唯一
    public DataSource firstDataSource() {
        return DataSourceBuilder.create().build();
    }
    @Primary
    @Bean(name = "firstEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary (EntityManagerFactoryBuilder builder) {
        return builder
                .dataSource(firstDataSource())
                .properties(getVendorProperties(firstDataSource()))
                .packages("com.wuwii.module.system.entity") //设置该数据源对应的实体类所在位置
                .persistenceUnit("firstPersistenceUnit")
                .build();
    }

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

    @Primary
    @Bean(name = "firstTransactionManager")
    public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
    }

}
  • secondDataSource
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "secondEntityManagerFactory",
        transactionManagerRef = "secondTransactionManager",
        basePackages = "com.wuwii.module.user.dao" // 设置该数据源 dao 层所在的位置
)
public class SecondDataSourceConfig {

    @Autowired
    private JpaProperties jpaProperties;
    @Bean(name = "secondEntityManager")
    public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
        return entityManagerFactoryPrimary(builder).getObject().createEntityManager();
    }


    @ConfigurationProperties(prefix = "spring.second-datasource")
    @Bean("secondDataSource")
    public DataSource secondDataSource() {
        return DataSourceBuilder.create().build();
    }
    @Bean(name = "secondEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary (EntityManagerFactoryBuilder builder) {
        return builder
                .dataSource(secondDataSource())
                .properties(getVendorProperties(secondDataSource()))
                .packages("com.wuwii.module.user.entity") //设置该数据源锁对应的实体类所在的位置
                .persistenceUnit("secondPersistenceUnit")
                .build();
    }

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

    @Bean(name = "secondTransactionManager")
    public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
    }

}
测试
@SpringBootTest
@RunWith(SpringRunner.class)
public class TestDemo {
    @Autowired
    private EmployeeDao employeeDao;
    @Autowired
    private UserDao userDao;
    @Before
    public void before() {
        employeeDao.deleteAll();
        userDao.deleteAll();
    }

    @Test
    public void test() {
        Employee employee = new Employee(null, "wuwii", 24);
        employeeDao.save(employee);
        User user = new User(null, "KronChan", 24);
        userDao.save(user);
        Assert.assertThat(employee, Matchers.equalTo(employeeDao.findOne(Example.of(employee))));
        Assert.assertThat(user, Matchers.equalTo(userDao.findOne(Example.of(user))));
    }
}

源码地址

免责声明:文章转载自《学习Spring Boot:(二十四)多数据源配置与使用》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇防止 iframe 的链接重定向父级页面sql语句如何获得当前日期下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

springboot postgresql druid连接池和jpa,jdbctemplate执行sql查询

1.maven依赖配置(pom.xml) 1 <dependency> 2 <groupId>org.springframework.boot</groupId> 3 <artifactId>spring-boot-starter</...

Hive扩展功能(六)--HPL/SQL(可使用存储过程)

软件环境: linux系统: CentOS6.7 Hadoop版本: 2.6.5 zookeeper版本: 3.4.8 ##主机配置: ######一共m1, m2, m3这五部机, 每部主机的用户名都为centos ``` 192.168.179.201: m1 192.168.179.202: m2 192.168.179.203: m3 m1:...

大数据自学3-Windows客户端DbVisualizer/SQuirreL配置连接hive

前面已经学习了将数据从Sql Server导入到Hive DB,并在Hue的Web界面可以查询,接下来是配置客户端工具直接连Hive数据库,常用的有DbVisualizer、SQuirreL SQL Client、DataGrip,只试用了前面两种,花了1天多时间最终实现了用这两款工具连Hive,还是挺有成就感的。 先把环境说明下,有些问题跟环境版本是非常...

Mybatis

JDBCJDBC相关概念 JAVA程序都是通过JDBC连接数据库的,通过SQL对数据库编程,JDBC是由SUN公司提出的一些列规范,只定义了接口规范,具体实现由各个数据库厂商去实现,它是一种典型的桥接模式。 桥接模式是一种结构型设计模式,它的主要特点是把抽象与行为实现分离开来,分别定义接口,可以保持各部分的独立性以及应对他们的功能扩展。 JDBC规范...

Error creating bean with name &amp;amp;#39;memcachedClient&amp;amp;#39;...java.lang.OutOfMemoryError

1,Tomcat启动报错例如以下: Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'memcachedClient' defined in file [/usr/local/apache-tomcat-...

设计模式-15 模板模式

一 模板模式   定义一个操作中的算法骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。也就是说:假如某些操作代码基本相同,只是其中一部分会经常改变,则可以使用模板方法,将不变的部分作为一个模板,将容易变动的部分让子类来实现。 关键代码:在抽象类实现,其他步骤在子类实现。 使用场景: Spirng 中对...