SpringBoot 2.x 在jpa中配置多数据源,与1.x还是存在稍许差别的,本示例基于
SpringBoot2.0.6
1. 下载依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
lombok
是一款插件,可以自动生成setter
,getter
等方法,适应起来十分方便可有减少编码量。
2. 配置多数据源配置信息
application.properties
#主
spring.datasource.jdbc-url=jdbc:mysql://192.168.2.222:3306/test1?useSSL=false&useUnicode=true&characterEncoding=utf-8
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=Haloo2018@
#从
spring.slave.datasource.jdbc-url=jdbc:mysql://192.168.2.222:3306/test1?useSSL=false&useUnicode=true&characterEncoding=utf-8
spring.slave.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.slave.datasource.username=root
spring.slave.datasource.password=Haloo2018@
spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=create
spring.jpa.hibernate.ddl-auto=create-drop
是hibernate.hbm2ddl.auto
的简称,create-drop
代表创建的时候自动生成表,会话结束删除表.
注意:
SpringBoot2.x默认使用的数据源是HikariCP
,它使用的连接参数是jdbc-url
而不是url
.
编写数据源配置类
@Configuration
public class DataSourceConfig {
@Bean("master")
@Primary
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource(){
return DataSourceBuilder.create().build();
}
@Bean("slave")
@ConfigurationProperties(prefix = "spring.slave.datasource")
public DataSource dataSourceSlave(){
return DataSourceBuilder.create().build();
}
}
必须有一个@Primary
作为主数据源,生成的@Bean
都将交给Spring
容器进行管理,所以在同类型有多个注册的情况下需要在@Bean
上定义别名,到时候注入的时候可以通过名称来进行注册,以免报错无法注入bean
。
配置数据源的JPA信息
前面的数据源仅仅配置的是一些连接参数,现在我们的JPA需要使用datasource
,所以需要对不同的数据源配置不同的JPA属性。
主:
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactoryMaster",//配置连接工厂 entityManagerFactory
transactionManagerRef = "transactionManagerMaster", //配置 事物管理器 transactionManager
basePackages = {"com.ztemap.datasource.repository"}
)
public class MasterDataSourceConfig {
@Autowired
@Qualifier("master")
private DataSource dataSourceMaster;
@Autowired
private JpaProperties jpaProperties;
@Bean("entityManagerMaster")
@Primary
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactoryBean(builder).getObject().createEntityManager();
}
@Bean("entityManagerFactoryMaster")
@Primary
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(EntityManagerFactoryBuilder builder) {
return builder.dataSource(dataSourceMaster)
.properties(getVendorProperties())
.packages("com.ztemap.datasource")
//持久化单元名称,当存在多个EntityManagerFactory时,需要制定此名称
.persistenceUnit("masterPersistenceUnit")
.build();
}
private Map getVendorProperties() {
HibernateSettings hibernateSettings = new HibernateSettings();
// hibernateSettings.ddlAuto(ddlAuto);
return jpaProperties.getHibernateProperties(hibernateSettings);
}
@Bean("transactionManagerMaster")
@Primary
public PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactoryBean(builder).getObject());
}
}
从:
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef="entityManagerFactorySlave",
transactionManagerRef = "transactionManagerSlave",
basePackages = {"com.ztemap.datasource.slave"}
)
public class SlaveDataSourceConfig {
@Autowired
@Qualifier("slave")
private DataSource dataSource;
@Autowired
private JpaProperties jpaProperties;
@Bean("entityManagerFactorySlave")
public LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean(EntityManagerFactoryBuilder builder) {
return builder.dataSource(dataSource)
.properties(getVendorProperties())
.packages("com.ztemap.datasource")
.build();
}
@Bean("entityManagerSlave")
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return localContainerEntityManagerFactoryBean(builder).getObject().createEntityManager();
}
@Bean("transactionManagerSlave")
public PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(localContainerEntityManagerFactoryBean(builder).getObject());
}
private Map getVendorProperties() {
HibernateSettings hibernateSettings = new HibernateSettings();
// hibernateSettings.ddlAuto(ddlAuto);
return jpaProperties.getHibernateProperties(hibernateSettings);
}
}
entityManagerFactoryRef
映射LocalContainerEntityManagerFactoryBean
对应的bean
名称,表示配置连接工厂
同理transactionManagerMaster
也是一样,表示的是事务管理器
basePackages
扫描的是继承JpaRepository<Student,Integer>
等类所在的包,packages
扫描的是实体类所在的包。
编写数据访问层接口
首先写两个实体类
Message,Student
@Data
@Entity
@AllArgsConstructor
public class Student {
@Id
@GeneratedValue
private Integer id;
private String name;
public Student(String name) {
this.name = name;
}
}
@Entity
@Data
public class Message {
@Id
@GeneratedValue
private Long id;
@Column(nullable = false)
private String name;
@Column(nullable = false)
private String content;
public Message(){}
public Message(String name, String content) {
this.name = name;
this.content = content;
}
}
数据访问层
public interface MessageRepository extends JpaRepository<Message, Long> {
}
@Repository
public interface StudentRepository extends JpaRepository<Student,Integer> {
}
注意: 需要将两个结构放置在不同的包下。