内容简介:大多数情况下,我们开发的应用程序需要单个数据源才能运行。在开发单个数据源Spring Boot应用程序时,配置非常简单。这只是在application.properties文件中定义一些属性的问题。以下是这样的配置,其中显示了如何定义基于MySQL的数据源。
Spring Boot 是一个非常强大的框架,可以非常轻松地用于开发基于Spring的应用程序。这个框架最好的事情是什么?您只需使用 Java 注释即可轻松完成高级配置。因此,您可以将重点放在业务逻辑而不是应用程序配置上。虽然Spring Boot应用程序默认使用单个数据源,但也可以使它们与多个数据源一起使用。
单个数据源
大多数情况下,我们开发的应用程序需要单个数据源才能运行。在开发单个数据源Spring Boot应用程序时,配置非常简单。这只是在application.properties文件中定义一些属性的问题。以下是这样的配置,其中显示了如何定义基于 MySQL 的数据源。
# DB connection properties spring.datasource.url=jdbc:mysql:<font><i>//host:3306/MY_DB</i></font><font> spring.datasource.username = dbUser spring.datasource.password = password spring.datasource.driver-<b>class</b>-name=com.mysql.cj.jdbc.Driver # JPA properties spring.jpa.hibernate.ddl-auto = validate spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect </font>
一旦正确定义了上述属性,您剩下要做的就是在JPA级别上。那就是编写Model类来表示表并编写Repositories来访问这些表。Spring在引擎盖下照顾其余的!
现在假设您有2个现有的后端应用程序在2个独立的数据源上工作。并且需要开发单个SB应用程序来管理这两个数据源上的数据。
那么如何使用单个Spring Boot应用程序配置多个数据源?这有可能吗?
多个数据源
这绝对是可能的,而不是那么复杂。它只需要用Spring的注释编写一些配置类。然后在application.properties文件中定义数据源连接属性,并正确地将存储库和模型组织到包中。所以让我们先看看后面的第一个。
管理模型和存储库包:
包组织是配置多个数据源的主要先决条件之一。确切地说,与2个数据源相关的模型类和存储库类应该在单独的包中。
例如,假设我们有2个数据源作为A和B.与数据源A相关的存储库类可以在一个或多个包中,我们将其假设为包com.udith.p和com.udith.q。条件是数据源B的存储库不能位于com.udith.p或com.udith.q包中。但是如果需要,它们可以位于com.udith.ps之类的子包中。
同样的条件也适用于Model类。但请注意,这不适用于Controller和Service类。
因此,对于此示例,我们假设存储库和模型的包如下所示:
模型: 数据源A: com.udith.model.p com.udith.model.q 数据源B: com.udith.model.r com.udith.model.s 仓储: 数据源A: com.udith.repo.p com.udith.repo.q 数据源B: com.udith.repo.r com.udith.repo.s
定义连接属性
当我们使用单个数据源时,我们使用“ spring.datasource。”前缀定义连接属性名称。例如,连接URL定义如下。
spring.datasource.url=jdbc:mysql://localhost:3306/MY_DB
但是,当使用多个数据源时,要求是每个数据源的连接属性名称应具有不同的前缀。所以让我们定义我们的2个数据源属性如下。
# Connection properties of Data Source A spring.datasource.a.url=jdbc:mysql:<font><i>//host1:3306/MY_DB_A</i></font><font> spring.datasource.a.username = dbUserA spring.datasource.a.password = passwordForA spring.datasource.a.driver-<b>class</b>-name=com.mysql.cj.jdbc.Driver # Connection properties of Data Source B spring.datasource.b.url=jdbc:mysql:</font><font><i>//host2:3306/MY_DB_B</i></font><font> spring.datasource.b.username = dbUserB spring.datasource.b.password = passwordForB spring.datasource.b.driver-<b>class</b>-name=com.mysql.cj.jdbc.Driver </font>
请注意,这些前缀可以是您喜欢的任何有效属性名称,并且不必以spring.datasource开头。
编写配置类
所以让我们进入Configuration类。您所要做的就是为每个数据源编写如下2个配置类。每个类都将为数据源,实体管理器工厂和事务管理器定义Spring bean。
所以这是我们的数据源A的配置类:
@Configuration @EnableTransactionManagement @EnableJpaRepositories(basePackages = {<font>"com.udith.repo.p"</font><font>, </font><font>"com.udith.repo.q"</font><font>}) <b>public</b> <b>class</b> ConfigA { @Primary @Bean(name = </font><font>"dataSourceA"</font><font>) @ConfigurationProperties(prefix = </font><font>"spring.datasource.a"</font><font>) <b>public</b> DataSource dataSource() { <b>return</b> DataSourceBuilder.create().build(); } @Primary @Bean(name = </font><font>"entityManagerFactoryA"</font><font>) <b>public</b> LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder, @Qualifier(</font><font>"dataSourceA"</font><font>) DataSource dataSource) { <b>return</b> builder .dataSource(dataSource) .packages(</font><font>"com.udith.model.p"</font><font>, </font><font>"com.udith.model.q"</font><font>) .persistenceUnit(</font><font>"datasourceA"</font><font>) .build(); } @Primary @Bean(name = </font><font>"transactionManagerA"</font><font>) <b>public</b> PlatformTransactionManager transactionManager(@Qualifier(</font><font>"entityManagerFactoryA"</font><font>) EntityManagerFactory entityManagerFactory) { <b>return</b> <b>new</b> JpaTransactionManager(entityManagerFactory); } } </font>
这是数据源B的那个:
@Configuration @EnableTransactionManagement @EnableJpaRepositories(basePackages = {<font>"com.udith.repo.r"</font><font>, </font><font>"com.udith.repo.s"</font><font>}) <b>public</b> <b>class</b> ConfigB { @Bean(name = </font><font>"dataSourceB"</font><font>) @ConfigurationProperties(prefix = </font><font>"spring.datasource.b"</font><font>) <b>public</b> DataSource dataSource() { <b>return</b> DataSourceBuilder.create().build(); } @Primary @Bean(name = </font><font>"entityManagerFactoryB"</font><font>) <b>public</b> LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder, @Qualifier(</font><font>"dataSourceB"</font><font>) DataSource dataSource) { <b>return</b> builder .dataSource(dataSource) .packages(</font><font>"com.udith.model.r"</font><font>, </font><font>"com.udith.model.s"</font><font>) .persistenceUnit(</font><font>"datasourceB"</font><font>) .build(); } @Primary @Bean(name = </font><font>"transactionManagerB"</font><font>) <b>public</b> PlatformTransactionManager transactionManager(@Qualifier(</font><font>"entityManagerFactoryB"</font><font>) EntityManagerFactory entityManagerFactory) { <b>return</b> <b>new</b> JpaTransactionManager(entityManagerFactory); } } </font>
现在让我们简要讨论一下上面配置类中使用的一些重要注释。
- 在每个配置类的顶部,@EnableJpaRepositories注释随属性一起添加basePackages。在此属性中,我们定义了包含与此特定数据源相关的JPA存储库类的Java包。
- 然后我们定义方法,为该数据源创建实例。此方法还具有属性的注释,该注释告诉Spring 在创建此数据源实例时应使用前缀为给定值的属性(来自application.properties文件)。dataSource()javax.sql.DataSource@ConfigurationPropertiesprefix
- 下一个方法entityManagerFactory负责为数据源创建bean。这里我们将先前创建的数据源实例作为方法参数传递,并使用构建器实例生成实体管理器工厂,提供包含与此数据源相关的模型类的Java包的名称。org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean
- 最后,transactionManager方法创建要用于此数据源的实例。org.springframework.transaction.PlatformTransactionManager
- 此外,您可能已经注意到,@Primary只有第一个配置类的bean定义中才有注释。这个注释告诉Spring使用第一个配置类中定义的数据源,实体管理器工厂和事务管理器作为主bean。
自定义JPA属性
如果您已完成到目前为止的步骤,则已完成使用多个数据源的基本要求。但在某些情况下,可能需要自定义一些JPA属性,例如,使用的命名策略。
当使用单个数据源时,也可以通过在application.properties文件中定义属性来完成这些操作。例如,您可以按如下方式设置命名策略。
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
但是,当使用基于配置文件的数据源时(正如我们在前面的步骤中所做的那样),由于某种原因,不会应用application.properties文件中定义的这些属性。因此,我们必须通过代码将它们传递给实体管理器工厂构建器,如下所示。
@Primary @Bean(name = <font>"entityManagerFactoryA"</font><font>) <b>public</b> LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder, @Qualifier(</font><font>"dataSourceA"</font><font>) DataSource dataSource) { Map jpaProperties = <b>new</b> HashMap<>(); jpaProperties.put(</font><font>"hibernate.naming_strategy"</font><font>, ImprovedNamingStrategy.<b>class</b>.getName()); </font><font><i>// any other customized JPA properties</i></font><font> <b>return</b> builder .dataSource(dataSource) .packages(</font><font>"com.udith.model.p"</font><font>, </font><font>"com.udith.model.q"</font><font>) .persistenceUnit(</font><font>"datasourceA"</font><font>) .properties(jpaProperties) .build(); } </font>
完成此步骤后,您已使用Spring Boot应用程序成功配置了多个数据源。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 当查询的数据来自多个数据源,有哪些好的分页策略?
- Spring Profile和Mybatis进行多个数据源(H2和Mysql)的切换
- TeaWeb v0.0.10 发布,增加多个监控数据源,增加 Agent 集群部署
- 搞定 Spring Boot 多数据源(二):动态数据源
- 数据源管理 | 基于JDBC模式,适配和管理动态数据源
- 苞米豆-多数据源 3.4.0 发布:本地多数据源事务优化
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
超级连接者:破解新互联时代的成功密码
伊桑•祖克曼(ETHAN ZUCKERMAN) / 林玮、张晨 / 浙江人民出版社 / 2018-8-1 / CNY 72.90
● 我们生活在一个互联互通的世界,我们需要辩证地看待某些事件,发现隐藏在背后的真相。着眼当下,看清彼此之间的联系,而非凭空幻想未来世界联系之紧密。数字世界主义要求我们承担起责任,让隐藏的联系变成现实。 ● 我们对世界的看法是局限的、不完整的、带有偏见的。如果我们想要改变从这个广阔的世界所获取的信息,我们需要做出结构性的改变。 ● 建立联系是一种新的力量。无论是在国家层面、企业层面还是个......一起来看看 《超级连接者:破解新互联时代的成功密码》 这本书的介绍吧!