SpringBoot--JPA--多数据源配置

        使用SpringBoot JPA来配置多数据源,实现对于多数据的读写操作,SpringBoot版本为2.1.3.RELEASE,由于不同的SpringBoot版本配置相差太大要特别注意,尽量查看官网文档。

导入Maven依赖

<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.3.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>vehicle</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>vehicle</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>	
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency> 
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<!--定时任务和@Slf4j注解日志的依赖-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- JPA Data (We are going to use Repositories, Entities, Hibernate, etc...) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <!-- Use MySQL Connector-J -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency> 
           
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>	
		</plugins>
	</build>

代码包组织结构

DemoApplicaton作为程序main方法入口,代码组织结构基本按照经典model dao service controller来组织,这里为了简便测试,去掉了service层,事务管理加载repository层。

                                                                  

首先注意DemoApplicaiton类的位置,作为SpringBoot程序入口类,其默认扫描类的规则是:与其同一级或者下一级,若想要扫描其他包类则可以使用注解@ComponentScan(basePackages="com.putian")

@SpringBootApplication
@ComponentScan(basePackages="com.putian")
public class DemoApplication {
	
	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}

}

配置文件

applicaiton.properties配置文件如下,SpringBoot理念是“约定优于配置”,前提是得熟悉这些默认的约定,配置文件以及注解不熟悉的话实在太难搞。其实配置文件中的配置项一般在项目启动时都加载到某个具体的配置类中作为基本属性来使用,因此找到具体的配置类就可以明确配置项的名称以及使用规则等。

#服务器开放端口
server.port=8888

#spring.data.elasticsearch.repositories.enabled=true
#es连接地址
#spring.data.elasticsearch.cluster-nodes = 10.3.10.144:9300
#es集群名称
#spring.data.elasticsearch.cluster-name = es

#This is the default for MySQL, no change to the database structure.
spring.jpa.hibernate.ddl-auto=none
spring.jpa.database=MYSQL
spring.jpa.show-sql=true
spring.jpa.generate-ddl=true


#spring.datasource.url=jdbc:mysql://10.3.10.172:3306/ac-device
#spring.datasource.username=root
#spring.datasource.password=Smart@001

spring.datasource.primary.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.primary.jdbc-url=jdbc:mysql://127.0.0.1:3306/ac-device?characterEncoding=utf8&serverTimezone=UTC
spring.datasource.primary.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.primary.username=root
spring.datasource.primary.password=1234
# JPA hikari 数据库连接池配置
spring.datasource.primary.hikari.maximum-pool-size=20
spring.datasource.primary.hikari.minimum-idle=5

spring.datasource.secondary.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.secondary.jdbc-url=jdbc:mysql://127.0.0.1:3306/warehouse?characterEncoding=utf8&serverTimezone=UTC
spring.datasource.secondary.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.secondary.username=root
spring.datasource.secondary.password=1234
# JPA hikari 数据库连接池配置
spring.datasource.secondary.hikari.maximum-pool-size=20
spring.datasource.secondary.hikari.minimum-idle=5

多数据的配置

多数据源的配置核心在于数据源的分别配置以及不同数据源与实体类,repository以及事务的分别映射。

配置主数据源以及从数据源

@Configuration
public class DataSourceConfig {
	
	@Bean(name="primaryDataSource")
	@Qualifier("primaryDataSource")
	@ConfigurationProperties(prefix = "spring.datasource.primary")
	public DataSource primatyDataSource() {
		return DataSourceBuilder.create().build();
	}
	
	@Bean(name="secondaryDataSource")
	@Qualifier("secondaryDataSource")
	@ConfigurationProperties(prefix = "spring.datasource.secondary")
	public DataSource secondaryDataSource() {
		return DataSourceBuilder.create().build();
	}

}

主数据源的详细配置

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef="entityManagerPrimary",
        transactionManagerRef="transactionManagerPrimary",
        basePackages= { "com.putian.repository.acdevice" }) //设置Repository所在位置
public class PrimaryConfig {
	
	@Primary
    @Bean
    PlatformTransactionManager transactionManagerPrimary() {
        return new JpaTransactionManager(entityManagerPrimary().getObject());
    }

    @Primary
    @Bean(name = "entityManagerPrimary")
    public LocalContainerEntityManagerFactoryBean entityManagerPrimary() {
        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setDatabase(Database.MYSQL);
        vendorAdapter.setShowSql(true);

        LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
        factoryBean.setDataSource(primaryDataSource);
        factoryBean.setJpaVendorAdapter(vendorAdapter);
        factoryBean.setPackagesToScan("com.putian.model.acdevice");
        return factoryBean;
    }

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


}

从数据源的详细配置

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef="entityManagerSecondary",
        transactionManagerRef="transactionManagerSecondary",
        basePackages= { "com.putian.repository.warehouse" }) //设置Repository所在位置
public class SecondaryConfig {

	@Autowired
    private DataSource secondaryDataSource;


    @Bean
    PlatformTransactionManager transactionManagerSecondary() {
        return new JpaTransactionManager(entityManagerSecondary().getObject());
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerSecondary() {
        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setGenerateDdl(true);
        vendorAdapter.setDatabase(Database.MYSQL);
        vendorAdapter.setShowSql(true);

        LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
        factoryBean.setDataSource(secondaryDataSource);
        factoryBean.setJpaVendorAdapter(vendorAdapter);
        factoryBean.setPackagesToScan("com.putian.model.warehouse");
        return factoryBean;
    }

}

数据源对应实体类是通过LocalContainerEntityManagerFactoryBean.setPackagesToScan方法来实现对应的。

数据源对应Repository类是通过注解@EnableJpaRepositories中basePackages来实现的。

从代码来看,数据源的配置项主要包括EntityManager,TransactionManager以及基本实体类包路径,不同的SpringBoot版本对于EntityManager配置差异较大,这里2.1.3形式配置方式如上所示,之前旧版本如下所示:

https://www.cnblogs.com/fengmao/p/7538854.html

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

    @Autowired
    private JpaProperties jpaProperties;

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

之后根据数据库表结构以及具体的需求编写model以及repository即可。

核心注解解析

1.@Configuration注解

* Indicates that a class declares one or more {@link Bean @Bean} methods and
 * may be processed by the Spring container to generate bean definitions and
 * service requests for those beans at runtime

该注解主要用于表示该类里面声明了Bean,需要由Spring容器来产生bean的定义。

2.@Bean注解

Indicates that a method produces a bean to be managed by the Spring container.

表明该方法将产生一个Spring容器管理的Bean,Bean名称默认与方法名相同,也可以通过name属性来指定。

3.@Qualifier注解

* This annotation may be used on a field or parameter as a qualifier for
 * candidate beans when autowiring. It may also be used to annotate other
 * custom annotations that can then in turn be used as qualifiers.

可以参考https://blog.csdn.net/qq_36567005/article/details/80611139

4.@ConfigurationProperties注解

可以简单认为下面Bean的配置项由配置文件中具有某些特殊规则前缀的项来对应

    @Bean(name="primaryDataSource")
	@Qualifier("primaryDataSource")
	@ConfigurationProperties(prefix = "spring.datasource.primary")
	public DataSource primatyDataSource() {
		return DataSourceBuilder.create().build();
	}
* Annotation for externalized configuration. Add this to a class definition or a
 * {@code @Bean} method in a {@code @Configuration} class if you want to bind and validate
 * some external Properties (e.g. from a .properties file).
     /**
	 * The name prefix of the properties that are valid to bind to this object. Synonym
	 * for {@link #prefix()}. A valid prefix is defined by one or more words separated
	 * with dots (e.g. {@code "acme.system.feature"}).
	 * @return the name prefix of the properties to bind
	 */

即primaryDataSource Bean中配置项由系统配置属性中具有前缀spring.datasource.primary来对应,与配置文件相对应

spring.datasource.primary.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.primary.jdbc-url=jdbc:mysql://127.0.0.1:3306/ac-device?characterEncoding=utf8&serverTimezone=UTC
spring.datasource.primary.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.primary.username=root
spring.datasource.primary.password=1234
# JPA hikari 数据库连接池配置
spring.datasource.primary.hikari.maximum-pool-size=20
spring.datasource.primary.hikari.minimum-idle=5

下面具体研究一下DataSource Bean是如何与配置文件中配置参数对应的

DataSourceBuilder.create().build();

build方法

@SuppressWarnings("unchecked")
	public T build() {
		Class<? extends DataSource> type = getType();
		DataSource result = BeanUtils.instantiateClass(type);
		maybeGetDriverClassName();
		bind(result);
		return (T) result;
	}

首先获取type属性,由type属性来实例化某种DataSource,其中type用来标识某种数据库连接池类型

private static final String[] DATA_SOURCE_TYPE_NAMES = new String[] {
			"com.zaxxer.hikari.HikariDataSource",
			"org.apache.tomcat.jdbc.pool.DataSource",
			"org.apache.commons.dbcp2.BasicDataSource" };

加载数据库连接的驱动类

private void maybeGetDriverClassName() {
		if (!this.properties.containsKey("driverClassName")
				&& this.properties.containsKey("url")) {
			String url = this.properties.get("url");
			String driverClass = DatabaseDriver.fromJdbcUrl(url).getDriverClassName();
			this.properties.put("driverClassName", driverClass);
		}
	}

如果配置属性中没有driverClassName,则从url属性汇总解析出驱动类

最后执行bind方法

private void bind(DataSource result) {
		ConfigurationPropertySource source = new MapConfigurationPropertySource(
				this.properties);
		ConfigurationPropertyNameAliases aliases = new ConfigurationPropertyNameAliases();
		aliases.addAliases("url", "jdbc-url");
		aliases.addAliases("username", "user");
		Binder binder = new Binder(source.withAliases(aliases));
		binder.bind(ConfigurationPropertyName.EMPTY, Bindable.ofInstance(result));
	}

可知DataSourceBuilder中属性是与配置文件中属性对应的。

5.@EnableJpaRepositories注解

6.@Primary注解

EntityManager构造过程

参考链接:

https://www.jianshu.com/p/c4cd03347daa

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.repositories

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Spring Boot中配置JPA多数据源的方法如下: 1. 首先,在pom.xml文件中添加必要的依赖项,包括Spring Boot、JPA和数据库驱动程序。 2. 创建对应的数据源配置类,包括数据库连接信息、用户名、密码等。可以创建多个数据源配置类,每个数据源对应一个数据库。 3. 创建对应的JdbcTemplate实例,用于在代码中执行SQL语句。每个数据源都需要创建一个对应的JdbcTemplate对象。 4. 创建指定数据源的方法,用于在代码中动态切换数据源。可以使用@Primary注解指定默认的数据源。 5. 创建Jpa事务管理器,用于管理多个数据源的事务。每个数据源都需要创建一个对应的Jpa事务管理器。 6. 使用AOP的切面来切换数据源。可以使用@Before和@After注解来分别在方法执行前和执行后进行数据源的切换和恢复。 以上是配置JPA多数据源的一般步骤,根据具体需求和情况,可能还需要进行一些额外的配置和调整。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [SpringBoot-JPA多数据源](https://blog.csdn.net/zZZ251682553/article/details/125105388)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [springboot jpa 多数据源配置](https://blog.csdn.net/chenxing1990/article/details/122808525)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值