SpringBoot配置多数据源( 五 )

这里配置了两个数据源,主要区别是数据库不同,其他都是一样的 。不过需要注意的是JPA多数据源配置与单独的JPA配置有所不同,因为后续的配置要从JpaProperties中的getProperties方法中获取所有JPA相关的配置,因此这里的属性前缀都是spring.jpa.properties 。
第四步,配置数据源 。新建一个config包,并在里面创建一个DataSourceConfig类,用于配置数据源,这样就可以根据application.properties文件来生成对应的DataSource 。里面的代码为:
@Configurationpublic class DataSourceConfig {@Bean@ConfigurationProperties("spring.datasource.one")@Primarypublic DataSource dsOne(){return DruidDataSourceBuilder.create().build();}@Bean@ConfigurationProperties("spring.datasource.two")public DataSource dsTwo(){return DruidDataSourceBuilder.create().build();}}不知道你是否注意到,此处在dsOne方法上添加了@Primary注解 。默认的@Autowired注解是依据类型进行注入,但是此处存在多个类型相同的对象,因此必须使用@Primary注解来指定优先注入哪个 。
第五步,创建Book实体类 。新建pojo包,并在里面创建Book实体类,里面的代码为:
@Entity(name = "t_user")@Datapublic class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Integer id;private String name;private String gender;private Integer age;}这样后续会根据实体类在数据库中创建t_user表,表中的id字段自增长 。
第六步,创建JPA配置 。接下来是核心配置,根据两个配置好的数据源来创建两个不同的JPA配置 。在config包内,新建两个JPA的配置类:JpaOneConfig和JpaTwoConfig,用于返回LocalContainerEntityManagerFactoryBean及事务管理器对象 。下面以JpaOneConfig配置类中的代码为例进行解释说明:
@Configuration@EnableTransactionManagement@EnableJpaRepositories(basePackages = "com.envy.jpamorespringboot.dao1",entityManagerFactoryRef = "entityManagerFactoryBeanOne",transactionManagerRef = "platformTransactionManagerOne")public class JpaOneConfig {@Resource(name = "dsOne")DataSource dsOne;@AutowiredJpaProperties jpaProperties;@Bean@PrimaryLocalContainerEntityManagerFactoryBean entityManagerFactoryBeanOne(EntityManagerFactoryBuilder builder){return builder.dataSource(dsOne).properties(jpaProperties.getProperties()).packages("com.envy.jpamorespringboot.pojo").persistenceUnit("pu1").build();}@BeanPlatformTransactionManager platformTransactionManagerOne(EntityManagerFactoryBuilder builder){LocalContainerEntityManagerFactoryBean factoryOne = entityManagerFactoryBeanOne(builder);return new JpaTransactionManager(factoryOne.getObject());}}解释一下上述代码的含义:

  • 使用@Configuration注解来标识这是一个配置类,接着使用@EnableJpaRepositories注解来进行JPA的配置,该注解中主要配置三个属性:basePackages、entityManagerFactoryRef和transactionManagerRef 。其中basePackages属性用于指定Repository的所在位置,entityManagerFactoryRef属性用于指定实体类管理工厂Bean的名称,transactionManagerRef属性则用来指定事务管理器的引用名称,这里的引用名称就是JpaOneConfig类中注册的Bean的名称(默认的Bean名称为方法名) 。
  • 然后创建entityManagerFactoryBeanOne方法,用于生成一个LocalContainerEntityManagerFactoryBean对象,而该对象用来提供EntityManager实例,在该类的创建过程中,首先配置数据源,然后设置JPA相关配置(JpaProperties由系统自动加载),再设置实体类所在的位置,最后配置持久化单元名,若项目中只有一个EntityManagerFactory,则persistenceUnit可以省略掉,若有多个,则必须明确指定持久化单元名 。
  • 由于项目中会提供两个LocalContainerEntityManagerFactoryBean实例,故需要在entityManagerFactoryBeanOne方法上添加@Primary注释,用于告诉Spring容器时优先使用该实例 。
  • platformTransactionManagerOne方法用于返回一个PlatformTransactionManager对象,实际上返回的是一个JpaTransactionManager对象,它提供对单个EntityManagerFactory的事务支持,专门用于解决JPA中的事务管理 。
上面是第一个JPA的配置信息,第二个JPA的配置与之相似,故这里仅仅只粘贴代码(需要注意的是第二个JPA类中的entityManagerFactoryBeanOne方法上不能添加@Primary注解):
@Configuration@EnableTransactionManagement@EnableJpaRepositories(basePackages = "com.envy.jpamorespringboot.dao2",entityManagerFactoryRef = "entityManagerFactoryBeanTwo",transactionManagerRef = "platformTransactionManagerTwo")public class JpaTwoConfig {@Resource(name = "dsTwo")DataSource dsTwo;@AutowiredJpaProperties jpaProperties;@BeanLocalContainerEntityManagerFactoryBean entityManagerFactoryBeanTwo(EntityManagerFactoryBuilder builder){return builder.dataSource(dsTwo).properties(jpaProperties.getProperties()).packages("com.envy.jpamorespringboot.pojo").persistenceUnit("pu2").build();}@BeanPlatformTransactionManager platformTransactionManagerTwo(EntityManagerFactoryBuilder builder){LocalContainerEntityManagerFactoryBean factoryOne = entityManagerFactoryBeanTwo(builder);return new JpaTransactionManager(factoryOne.getObject());}}


推荐阅读