Project structure
1. Dependence
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.18</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <!-- MySQL driver, note, this needs to correspond to the MySQL version --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.31</version> <scope>runtime</scope> </dependency> <!--web--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--fastjson--> <dependency> <groupId>com.alibaba.fastjson2</groupId> <artifactId>fastjson2</artifactId> <version>2.0.4</version> </dependency> </dependencies>
2.application.yml
server: port: 8900 #Port spring: datasource: #Main data source primary: url: jdbc:mysql://192.168.64.132:3306/testdb?serverTimezone=GMT & amp;seUnicode=true & amp;characterEncoding=UTF-8 & amp;useSSL=false & amp;allowMultiQueries=true & amp;autoReconnect= true &allowPublicKeyRetrieval=true username: root password: 123456 driver-class-name: com.mysql.jdbc.Driver type: com.zaxxer.hikari.HikariDataSource #From data source secondary: url: jdbc:mysql://192.168.64.132:3307/testdb?serverTimezone=GMT & amp;seUnicode=true & amp;characterEncoding=UTF-8 & amp;useSSL=false & amp;allowMultiQueries=true & amp;autoReconnect= true &allowPublicKeyRetrieval=true username: root password: 123456 driver-class-name: com.mysql.jdbc.Driver jpa: #Main jpa configuration primary: show-sql: true properties: hibernate: hbm2ddl: auto: update dialect: org.hibernate.dialect.MySQL8Dialect #Configure from jpa secondary: show-sql: true properties: hibernate: hbm2ddl: auto: update dialect: org.hibernate.dialect.MySQL8Dialect
3. Primary data source configuration
package com.xiaoxi.demo.config.primaryconfig; import org.springframework.beans.factory.annotation.Qualifier; 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.context.annotation.Primary; import org.springframework.jdbc.core.JdbcTemplate; import javax.sql.DataSource; @Configuration public class PrimaryDataSourceConfig { /** * Scan the configuration information starting with spring.datasource.primary * * @return data source configuration information */ @Primary @Bean(name = "primaryDataSourceProperties") @ConfigurationProperties(prefix = "spring.datasource.primary") public DataSourceProperties dataSourceProperties() { return new DataSourceProperties(); } /** * Get the main database data source object * * @param dataSourceProperties injects a bean named primaryDataSourceProperties * @return data source object */ @Primary @Bean(name = "primaryDataSource") public DataSource dataSource(@Qualifier("primaryDataSourceProperties") DataSourceProperties dataSourceProperties) { return dataSourceProperties.initializeDataSourceBuilder().build(); } /** * This method is only used when you need to use the JdbcTemplate object * * @param dataSource injects a bean named primaryDataSource * @return data source JdbcTemplate object */ @Primary @Bean(name = "primaryJdbcTemplate") public JdbcTemplate jdbcTemplate(@Qualifier("primaryDataSource") DataSource dataSource) { return new JdbcTemplate(dataSource); } }
4.Creation of main entity class
package com.xiaoxi.demo.entity.primaryentity; import lombok.Data; import javax.persistence.*; @Data @Entity // jpa-specific, must be added @Table(name = "t_user") public class PrimaryTbUserEntity { @Id //primary key id @GeneratedValue(strategy= GenerationType.IDENTITY)//Primary key generation strategy @Column(name="id") //Database field name privateInteger id; @Column(name = "uname") private String uname; }
5. Main repository creation
package com.xiaoxi.demo.dao.primaryrepository; import com.xiaoxi.demo.entity.primaryentity.PrimaryTbUserEntity; import org.springframework.context.annotation.Primary; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository("primaryUserRepository") @Primary public interface PrimaryUserRepository extends JpaRepository<PrimaryTbUserEntity, Integer> { }
6. Main jpa configuration
package com.xiaoxi.demo.config.primaryconfig; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.sql.DataSource; @Configuration @EnableTransactionManagement @EnableJpaRepositories( basePackages = PrimaryJpaConfig.REPOSITORY_PACKAGE, entityManagerFactoryRef = "primaryEntityManagerFactory", transactionManagerRef = "primaryTransactionManager" ) public class PrimaryJpaConfig { static final String REPOSITORY_PACKAGE = "com.xiaoxi.demo.dao.primaryrepository"; private static final String ENTITY_PACKAGE = "com.xiaoxi.demo.entity.primaryentity"; /** * Scan the configuration information starting with spring.jpa.primary * * @return jpa configuration information */ @Primary @Bean(name = "primaryJpaProperties") @ConfigurationProperties(prefix = "spring.jpa.primary") public JpaProperties jpaProperties() { return new JpaProperties(); } /** * Get the main library entity management factory object * * @param primaryDataSource injects a data source named primaryDataSource * @param jpaProperties injects jpa configuration information named primaryJpaProperties * @param builder injects EntityManagerFactoryBuilder * @return entity management factory object */ @Primary @Bean(name = "primaryEntityManagerFactory") public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean( @Qualifier("primaryDataSource") DataSource primaryDataSource, @Qualifier("primaryJpaProperties") JpaProperties jpaProperties, EntityManagerFactoryBuilder builder ) { return builder //Set data source .dataSource(primaryDataSource) //Set jpa configuration .properties(jpaProperties.getProperties()) //Set the entity package name .packages(ENTITY_PACKAGE) //Set the persistence unit name, which is used to specify the data source when the @PersistenceContext annotation obtains the EntityManager. .persistenceUnit("primaryPersistenceUnit").build(); } /** * Get entity management object * * @param factory injects a bean named primaryEntityManagerFactory * @return entity management object */ @Primary @Bean(name = "primaryEntityManager") public EntityManager entityManager(@Qualifier("primaryEntityManagerFactory") EntityManagerFactory factory) { return factory.createEntityManager(); } /** * Get the main database transaction management object * * @param factory injects a bean named primaryEntityManagerFactory * @return transaction management object */ @Primary @Bean(name = "primaryTransactionManager") public PlatformTransactionManager transactionManager(@Qualifier("primaryEntityManagerFactory") EntityManagerFactory factory) { return new JpaTransactionManager(factory); } }
7. Configure from data source
package com.xiaoxi.demo.config.secondaryconfig; import org.springframework.beans.factory.annotation.Qualifier; 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 SecondaryDataSourceConfig { /** * Scan the configuration information starting with spring.datasource.secondary * * @return data source configuration information */ @Bean(name = "secondaryDataSourceProperties") @ConfigurationProperties(prefix = "spring.datasource.secondary") public DataSourceProperties dataSourceProperties() { return new DataSourceProperties(); } /** * Get the secondary data source object * * @param dataSourceProperties injects a bean named secondaryDataSourceProperties * @return data source object */ @Bean("secondaryDataSource") public DataSource dataSource(@Qualifier("secondaryDataSourceProperties") DataSourceProperties dataSourceProperties) { return dataSourceProperties.initializeDataSourceBuilder().build(); } /** * This method is only used when you need to use the JdbcTemplate object * * @param dataSource injects a bean named secondaryDataSource * @return data source JdbcTemplate object */ @Bean(name = "secondaryJdbcTemplate") public JdbcTemplate jdbcTemplate(@Qualifier("secondaryDataSource") DataSource dataSource) { return new JdbcTemplate(dataSource); } }
8. Configure from jpa
package com.xiaoxi.demo.config.secondaryconfig; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.sql.DataSource; @Configuration @EnableTransactionManagement @EnableJpaRepositories( basePackages = SecondaryJpaConfig.REPOSITORY_PACKAGE, entityManagerFactoryRef = "secondaryEntityManagerFactory", transactionManagerRef = "secondaryTransactionManager" ) public class SecondaryJpaConfig { static final String REPOSITORY_PACKAGE = "com.xiaoxi.demo.dao.secondaryrepository"; private static final String ENTITY_PACKAGE = "com.xiaoxi.demo.entity.secondaryentity"; /** * Scan spring.jpa.secondary * * @return jpa configuration information */ @Bean(name = "secondaryJpaProperties") @ConfigurationProperties(prefix = "spring.jpa.secondary") public JpaProperties jpaProperties() { return new JpaProperties(); } /** * Get the secondary library entity management factory object * * @param secondaryDataSource injects a data source named secondaryDataSource * @param jpaProperties injects jpa configuration information named secondaryJpaProperties * @param builder injects EntityManagerFactoryBuilder * @return entity management factory object */ @Bean(name = "secondaryEntityManagerFactory") public LocalContainerEntityManagerFactoryBean entityManagerFactory( @Qualifier("secondaryDataSource") DataSource secondaryDataSource, @Qualifier("secondaryJpaProperties") JpaProperties jpaProperties, EntityManagerFactoryBuilder builder ) { return builder //Set data source .dataSource(secondaryDataSource) //Set jpa configuration .properties(jpaProperties.getProperties()) //Set the entity package name .packages(ENTITY_PACKAGE) //Set the persistence unit name, which is used to specify the data source when the @PersistenceContext annotation obtains the EntityManager. .persistenceUnit("secondaryPersistenceUnit").build(); } /** * Get entity management object * * @param factory injects a bean named secondaryEntityManagerFactory * @return entity management object */ @Bean(name = "secondaryEntityManager") public EntityManager entityManager(@Qualifier("secondaryEntityManagerFactory") EntityManagerFactory factory) { return factory.createEntityManager(); } /** * Get the main database transaction management object * * @param factory injects a bean named secondaryEntityManagerFactory * @return transaction management object */ @Bean(name = "secondaryTransactionManager") public PlatformTransactionManager transactionManager(@Qualifier("secondaryEntityManagerFactory") EntityManagerFactory factory) { return new JpaTransactionManager(factory); } }
9. Configuration from entity class
package com.xiaoxi.demo.entity.secondaryentity; import lombok.Data; import javax.persistence.*; @Data @Entity // jpa-specific, must be added @Table(name = "t_user") public class SecondaryTbUserEntity { @Id //primary key id @GeneratedValue(strategy= GenerationType.IDENTITY)//Primary key generation strategy @Column(name="id") //Database field name privateInteger id; @Column(name = "uname") private String name; }
10. Create from repository
package com.xiaoxi.demo.dao.secondaryrepository; import com.xiaoxi.demo.entity.secondaryentity.SecondaryTbUserEntity; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository("secondaryUserRepository") public interface SecondaryUserRepository extends JpaRepository<SecondaryTbUserEntity, Integer> { }
11. Configure from jpa
package com.xiaoxi.demo.config.secondaryconfig; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.sql.DataSource; @Configuration @EnableTransactionManagement @EnableJpaRepositories( basePackages = SecondaryJpaConfig.REPOSITORY_PACKAGE, entityManagerFactoryRef = "secondaryEntityManagerFactory", transactionManagerRef = "secondaryTransactionManager" ) public class SecondaryJpaConfig { static final String REPOSITORY_PACKAGE = "com.xiaoxi.demo.dao.secondaryrepository"; private static final String ENTITY_PACKAGE = "com.xiaoxi.demo.entity.secondaryentity"; /** * Scan spring.jpa.secondary * * @return jpa configuration information */ @Bean(name = "secondaryJpaProperties") @ConfigurationProperties(prefix = "spring.jpa.secondary") public JpaProperties jpaProperties() { return new JpaProperties(); } /** * Get the secondary library entity management factory object * * @param secondaryDataSource injects a data source named secondaryDataSource * @param jpaProperties injects jpa configuration information named secondaryJpaProperties * @param builder injects EntityManagerFactoryBuilder * @return entity management factory object */ @Bean(name = "secondaryEntityManagerFactory") public LocalContainerEntityManagerFactoryBean entityManagerFactory( @Qualifier("secondaryDataSource") DataSource secondaryDataSource, @Qualifier("secondaryJpaProperties") JpaProperties jpaProperties, EntityManagerFactoryBuilder builder ) { return builder //Set data source .dataSource(secondaryDataSource) //Set jpa configuration .properties(jpaProperties.getProperties()) //Set the entity package name .packages(ENTITY_PACKAGE) //Set the persistence unit name, which is used to specify the data source when the @PersistenceContext annotation obtains the EntityManager. .persistenceUnit("secondaryPersistenceUnit").build(); } /** * Get entity management object * * @param factory injects a bean named secondaryEntityManagerFactory * @return entity management object */ @Bean(name = "secondaryEntityManager") public EntityManager entityManager(@Qualifier("secondaryEntityManagerFactory") EntityManagerFactory factory) { return factory.createEntityManager(); } /** * Get the main database transaction management object * * @param factory injects a bean named secondaryEntityManagerFactory * @return transaction management object */ @Bean(name = "secondaryTransactionManager") public PlatformTransactionManager transactionManager(@Qualifier("secondaryEntityManagerFactory") EntityManagerFactory factory) { return new JpaTransactionManager(factory); } }
12. Test
package com.xiaoxi.demo.controllerr; import com.alibaba.fastjson2.JSON; import com.xiaoxi.demo.dao.primaryrepository.PrimaryUserRepository; import com.xiaoxi.demo.dao.secondaryrepository.SecondaryUserRepository; import com.xiaoxi.demo.entity.primaryentity.PrimaryTbUserEntity; import com.xiaoxi.demo.entity.secondaryentity.SecondaryTbUserEntity; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; import java.util.Map; import java.util.Optional; @RestController public class TestMutiDataSource { @Autowired PrimaryUserRepository primaryUserRepository; @Autowired @Qualifier("secondaryUserRepository") SecondaryUserRepository secondaryUserRepository; @GetMapping("/test") public String TestMutiDataSource() { Map<String, String> re = new HashMap<>(); Optional<PrimaryTbUserEntity> byId = primaryUserRepository.findById(1); if(byId.isPresent()) { re.put("Main database data", JSON.toJSONString(byId.get())); } Optional<SecondaryTbUserEntity> byIdSecondary = secondaryUserRepository.findById(2); if(byIdSecondary.isPresent()) { re.put("data from the database", JSON.toJSONString(byIdSecondary.get())); } return JSON.toJSONString(re); } } Print: { "Data from the database": "{"id":2,"name":"lisi4"}", "Main database data": "{"id":1,"uname":"zhang3"}" }
Summary:
To configure multiple data sources in jpa is to configure multiple repositories. Each repository corresponds to different data sources.