spring+Jpa多数据源配置的方法示例

网友投稿 231 2023-01-23


spring+Jpa多数据源配置的方法示例

今天临下班时遇到了一个需求,我的管理平台需要从不同的数据库中获取数据信息,这就需要进行Spring的多数据源配置,对于这种配置,第一次永远都是痛苦的,不过经历了这次的折磨,今后肯定会对这种配置印象深刻。我们这里简单回顾一下流程。

我们配置了两个数据库,一个是公司的数据库,另一个是我本地的一个数据库。首先是application.yml的配置(其中对于公司的数据库我们采取了假的地址,而本机的数据库是真是存在对应的表和库的)

数据库信息:

数据表信息:

1、application.yml

datasource:

primary:

url: jdbc:mysql://companyurl.com:5002/db1

username: unameq

zBlbMroJ 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、创建总的Dhttp://ataSource配置文件以及两个Repostory的配置文件PrimaryConfig以及SecondaryConfig

DataSourceConfig

@Configuration

public class DataSourceConfig {

@Bean(name = "primaryDataSource")

@Qualifier("primaryDataSource")

@ConfigurationProperties(prefix="spring.datasource.primary")//对应的数据库配置信息

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= { "数据访问层所在的包" }) //设置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("实体类所在的包") //设置实体类所在位置

.persistenceUnit("primaryPersistenceUnit")

.build();

}

@Autowired

private JpaProperties jpaProperties;

private Map 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= { "数据访问层所在的包" }) //设置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("实体类所在的包") //设置实体类所在位置

.persistenceUnit("secondaryPersistenceUnit")

.build();

}

@Autowired

private JpaProperties jpaProperties;

private Map getVendorProperties(DataSource dataSource) {

return jpaProperties.getHibernateProperties(dataSource);

}

@Bean(name = "transactionManagerSecondary")

PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) {

return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject());

}

}

3、然后我对于本地数据库新建实体类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 +

'}';

}

}

并创建对应的Repositoy,PeoplePersonDao并创建了一个findAll的方法

@Transactional@Repositorypublic interface PeoplePersonDao extends JpaRepository

{

List findAll();

}

4、最后,在test包中进行测试

@Autowired

private PeoplePersonDao peoplePersonDao;

@Test

public void testMultiDataSource() {

List list = peoplePersonDao.findAll();

for (int i = 0; i < list.size(); i++) {

logger.info(list.get(i).toString());

}

}

测试结果

一些坑

不仅仅是dao层扫描的包需要区分,对于实体类所在的包,不同的DataSource的配置中也需要区分开

对于这种套路性的东西,总结一遍是非常必要的,下次可以节省许多不必要的时间,对于内部原理,我将在完成对Ioc和Aop分析后反过来分析其原理。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:详解Spring Boot 项目部署到heroku爬坑
下一篇:远程共享文件系统有哪些(远程共享文件系统有哪些类型)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~