个人博客 1、添加多数据源的配置 1.1、yaml配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 server: port: 40300 spring: application: name: jpa-multi-datasource datasource: primary: jdbc-url: jdbc:mysql://148.70.153.63:3306/ttms?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false username: root password: password driver-class-name: com.mysql.cj.jdbc.Driver initialSize: 5 maxActive: 50 minIdle: 0 maxWait: 60000 useUnfairLock: true secondary: jdbc-url: jdbc:mysql://148.70.153.63:3306/ttms?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false username: root password: password driver-class-name: com.mysql.cj.jdbc.Driver initialSize: 3 maxActive: 10 minIdle: 0 maxWait: 60000 useUnfairLock: true jpa: show-sql: true hibernate: ddl-auto: update database: MYSQL
注意:
这里为了方便,2个数据源的配置是用同一个数据库。 如果使用默认的数据源,在SpringBoot2.x
以后需要使用jdbc-url
而非url
,否则会报 java.lang.IllegalArgumentException: jdbcUrl is required with driverClassName.
。 1.2、数据源配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @Configuration public class DataSourceConfig { @Primary @Bean @ConfigurationProperties(prefix = "spring.datasource.primary") public DataSource primaryDataSource () { return DataSourceBuilder.create().build(); } @Bean @ConfigurationProperties(prefix = "spring.datasource.secondary") public DataSource secondaryDataSource () { return DataSourceBuilder.create().build(); } }
数据源使用的是SpringBoot2.x
版本默认的HikariCP
连接池。@Primary
注解指定了主数据源。
1.3、JPA配置 1.3.1、Primary数据源的JPA配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 @Configuration @EnableTransactionManagement @EnableJpaRepositories( entityManagerFactoryRef="entityManagerFactoryPrimary", transactionManagerRef="transactionManagerPrimary", basePackages= { "net.zhaoxiaobin.jpa.dao.primary" }) public class PrimaryConfig { @Autowired private DataSource primaryDataSource; @Autowired private JpaProperties jpaProperties; @Autowired private HibernateProperties hibernateProperties; private Map<String, Object> getVendorProperties () { return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings()); } @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) .packages("net.zhaoxiaobin.jpa.domain.primary" ) .persistenceUnit("primaryPersistenceUnit" ) .properties(getVendorProperties()) .build(); } @Primary @Bean(name = "transactionManagerPrimary") public PlatformTransactionManager transactionManagerPrimary (EntityManagerFactoryBuilder builder) { return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject()); } }
Repository配置:
1 2 3 public interface PrimaryRepository extends JpaRepository <Actor ,Long > {}
实体类配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 @Entity @Table(name = "actor") @Data public class Actor { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "actor_name", nullable = false, length = 128, unique = true) private String actorName; @Column(name = "actor_age", nullable = false) private int actorAge; @Column(name = "actor_email", length = 64, unique = true) private String actorEmail; @Column(name = "create_time", nullable = false, length = 32) private String createTime = DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss SSS" ); }
1.3.2、Secondary数据源的JPA配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 @Configuration @EnableTransactionManagement @EnableJpaRepositories( entityManagerFactoryRef="entityManagerFactorySecondary", transactionManagerRef="transactionManagerSecondary", basePackages= { "net.zhaoxiaobin.jpa.dao.secondary" }) public class SecondaryConfig { @Autowired private DataSource secondaryDataSource; @Autowired private JpaProperties jpaProperties; @Autowired private HibernateProperties hibernateProperties; private Map<String, Object> getVendorProperties () { return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings()); } @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) .packages("net.zhaoxiaobin.jpa.domain.secondary" ) .persistenceUnit("secondaryPersistenceUnit" ) .properties(getVendorProperties()) .build(); } @Bean(name = "transactionManagerSecondary") public PlatformTransactionManager transactionManagerSecondary (EntityManagerFactoryBuilder builder) { return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject()); } }
Repository配置:
1 2 3 public interface SecondaryRepository extends JpaRepository <User ,Long > {}
实体类配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 @Entity @Table(name = "user") @Data public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "name",length = 64) private String name; @Column(name = "age") private int age; }
说明与注意 :
在使用JPA的时候,需要为不同的数据源创建不同的package来存放对应的Entity和Repository,以便于配置类的分区扫描。 类名上的注解@EnableJpaRepositories
中指定Repository的所在位置。 LocalContainerEntityManagerFactoryBean
创建的时候,指定Entity所在的位置。2、测试 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 @RunWith(SpringRunner.class) @SpringBootTest @Slf4j public class MultiDataSourceTest { @Autowired private PrimaryRepository primaryRepository; @Autowired private SecondaryRepository secondaryRepository; @Test public void testPrimary () { List<Actor> actorList = new ArrayList<>(); for (int i = 0 ; i < 5 ; i++) { Actor actor = new Actor(); actor.setActorName("actor" + i); actor.setActorEmail("email" + i); actor.setActorAge(i + 20 ); actorList.add(actor); } primaryRepository.saveAll(actorList); } @Test public void testSecondary () { List<User> userList = new ArrayList<>(); for (int i = 0 ; i < 5 ; i++) { User user = new User(); user.setName("userName" + i); user.setAge(i); userList.add(user); } secondaryRepository.saveAll(userList); } }
3、工程结构 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 ├── jpa-multi-datasource.iml ├── pom.xml └── src ├── main │ ├── java │ │ └── net │ │ └── zhaoxiaobin │ │ └── jpa │ │ ├── JpaMultiDatasourceApplication.java │ │ ├── config │ │ │ ├── DataSourceConfig.java │ │ │ ├── PrimaryConfig.java │ │ │ └── SecondaryConfig.java │ │ ├── dao │ │ │ ├── primary │ │ │ │ └── PrimaryRepository.java │ │ │ └── secondary │ │ │ └── SecondaryRepository.java │ │ └── domain │ │ ├── primary │ │ │ └── Actor.java │ │ └── secondary │ │ └── User.java │ └── resources │ ├── application.yml │ └── hibernate.properties └── test └── java └── net └── zhaoxiaobin └── jpa └── MultiDataSourceTest.java
参考链接 代码地址