spring+Jpa多數(shù)據(jù)源配置的方法示例
今天臨下班時(shí)遇到了一個(gè)需求,我的管理平臺(tái)需要從不同的數(shù)據(jù)庫中獲取數(shù)據(jù)信息,這就需要進(jìn)行Spring的多數(shù)據(jù)源配置,對(duì)于這種配置,第一次永遠(yuǎn)都是痛苦的,不過經(jīng)歷了這次的折磨,今后肯定會(huì)對(duì)這種配置印象深刻。我們這里簡單回顧一下流程。
我們配置了兩個(gè)數(shù)據(jù)庫,一個(gè)是公司的數(shù)據(jù)庫,另一個(gè)是我本地的一個(gè)數(shù)據(jù)庫。首先是application.yml的配置(其中對(duì)于公司的數(shù)據(jù)庫我們采取了假的地址,而本機(jī)的數(shù)據(jù)庫是真是存在對(duì)應(yīng)的表和庫的)
數(shù)據(jù)庫信息:
數(shù)據(jù)表信息:
1、application.yml
datasource: primary: url: jdbc:mysql://companyurl.com:5002/db1 username: unameq password: passwd1 driver-class-name: com.mysql.jdbc.Driver secondary: url: jdbc:mysql://localhost:3306/django_test username: root password: 123456 driver-class-name: com.mysql.jdbc.Driver jpa: database-platform: org.hibernate.dialect.MySQL5Dialect hibernate: ddl-auto: update show-sql: true
2、創(chuàng)建總的DataSource配置文件以及兩個(gè)Repostory的配置文件PrimaryConfig以及SecondaryConfig
DataSourceConfig
@Configuration public class DataSourceConfig { @Bean(name = "primaryDataSource") @Qualifier("primaryDataSource") @ConfigurationProperties(prefix="spring.datasource.primary")//對(duì)應(yīng)的數(shù)據(jù)庫配置信息 public DataSource primaryDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "secondaryDataSource") @Qualifier("secondaryDataSource") @Primary @ConfigurationProperties(prefix="spring.datasource.secondary") public DataSource secondaryDataSource() { return DataSourceBuilder.create().build(); } }
PrimaryConfig
@Configuration @EnableTransactionManagement @EnableJpaRepositories( entityManagerFactoryRef="entityManagerFactoryPrimary", transactionManagerRef="transactionManagerPrimary", basePackages= { "數(shù)據(jù)訪問層所在的包" }) //設(shè)置Repository所在位置 public class PrimaryConfig { @Autowired @Qualifier("primaryDataSource") private DataSource primaryDataSource; @Primary @Bean(name = "entityManagerPrimary") public EntityManager entityManager(EntityManagerFactoryBuilder builder) { return entityManagerFactoryPrimary(builder).getObject().createEntityManager(); } @Primary @Bean(name = "entityManagerFactoryPrimary") public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary (EntityManagerFactoryBuilder builder) { return builder .dataSource(primaryDataSource) .properties(getVendorProperties(primaryDataSource)) .packages("實(shí)體類所在的包") //設(shè)置實(shí)體類所在位置 .persistenceUnit("primaryPersistenceUnit") .build(); } @Autowired private JpaProperties jpaProperties; private Map<String, String> getVendorProperties(DataSource dataSource) { return jpaProperties.getHibernateProperties(dataSource); } @Primary @Bean(name = "transactionManagerPrimary") public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) { return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject()); } }
SecondaryConfig
@Configuration @EnableTransactionManagement @EnableJpaRepositories( entityManagerFactoryRef="entityManagerFactorySecondary", transactionManagerRef="transactionManagerSecondary", basePackages= { "數(shù)據(jù)訪問層所在的包" }) //設(shè)置Repository所在位置 public class SecondaryConfig { @Autowired @Qualifier("secondaryDataSource") private DataSource secondaryDataSource; @Bean(name = "entityManagerSecondary") public EntityManager entityManager(EntityManagerFactoryBuilder builder) { return entityManagerFactorySecondary(builder).getObject().createEntityManager(); } @Bean(name = "entityManagerFactorySecondary") public LocalContainerEntityManagerFactoryBean entityManagerFactorySecondary(EntityManagerFactoryBuilder builder) { return builder .dataSource(secondaryDataSource) .properties(getVendorProperties(secondaryDataSource)) .packages("實(shí)體類所在的包") //設(shè)置實(shí)體類所在位置 .persistenceUnit("secondaryPersistenceUnit") .build(); } @Autowired private JpaProperties jpaProperties; private Map<String, String> getVendorProperties(DataSource dataSource) { return jpaProperties.getHibernateProperties(dataSource); } @Bean(name = "transactionManagerSecondary") PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) { return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject()); } }
3、然后我對(duì)于本地?cái)?shù)據(jù)庫新建實(shí)體類PeoplePerson
@Entity @Table(name = "people_person") public class PeoplePerson implements Serializable { @Id @GeneratedValue private Integer id; @Column(name = "name") private String name; @Column(name = "age") private Integer age; public PeoplePerson() { } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "PeoplePerson{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + '}'; } }
并創(chuàng)建對(duì)應(yīng)的Repositoy,PeoplePersonDao并創(chuàng)建了一個(gè)findAll的方法
@Transactional@Repositorypublic interface PeoplePersonDao extends JpaRepository<PeoplePerson, Long> { List<PeoplePerson> findAll(); }
4、最后,在test包中進(jìn)行測(cè)試
@Autowired private PeoplePersonDao peoplePersonDao; @Test public void testMultiDataSource() { List<PeoplePerson> list = peoplePersonDao.findAll(); for (int i = 0; i < list.size(); i++) { logger.info(list.get(i).toString()); } }
測(cè)試結(jié)果
一些坑
不僅僅是dao層掃描的包需要區(qū)分,對(duì)于實(shí)體類所在的包,不同的DataSource的配置中也需要區(qū)分開
對(duì)于這種套路性的東西,總結(jié)一遍是非常必要的,下次可以節(jié)省許多不必要的時(shí)間,對(duì)于內(nèi)部原理,我將在完成對(duì)Ioc和Aop分析后反過來分析其原理。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
springMVC如何對(duì)輸入數(shù)據(jù)校驗(yàn)實(shí)現(xiàn)代碼
數(shù)據(jù)的校驗(yàn)是交互式網(wǎng)站一個(gè)不可或缺的功能,數(shù)據(jù)驗(yàn)證分為客戶端驗(yàn)證和服務(wù)器端驗(yàn)證,這篇文章主要介紹了springMVC如何對(duì)輸入數(shù)據(jù)校驗(yàn),需要的朋友可以參考下2020-10-10java中ThreadLocal的應(yīng)用場(chǎng)景實(shí)例分析
在本篇文章里小編給大家整理的是一篇關(guān)于java中ThreadLocal的應(yīng)用場(chǎng)景實(shí)例分析,對(duì)此有興趣的朋友們可以學(xué)習(xí)參考下。2021-02-02關(guān)于MyBatis中映射對(duì)象關(guān)系的舉例
這篇文章主要介紹了關(guān)于MyBatis中映射對(duì)象關(guān)系的舉例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06Spring Boot配置Swagger的實(shí)現(xiàn)代碼
這篇文章主要介紹了Spring Boot配置Swagger的實(shí)現(xiàn)代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-12-12