配置多数据源
创建一个Spring配置类,定义两个DataSourceConfig用来读取application.properties中的不同配置。如下例子中,主数据源配置为spring.datasource.primary开头的配置,第二数据源配置为spring.datasource.secondary开头的配置。
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.core.JdbcTemplate;
/**
* @Description:
* @Auther: Wangtianming
* @Date: 2021/12/21 17:08
*/
@Configuration
public class DataSourceConfig {
@Bean
@Qualifier("primaryDataSource")
@Primary
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@Qualifier("secondaryDataSource")
@ConfigurationProperties(prefix = "spring.datasource.secondary")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
//JdbcTemplate支持配置
//对JdbcTemplate的支持比较简单,只需要为其注入对应的datasource即可,如下例子,在创建JdbcTemplate的时候分别注入名为primaryDataSource和secondaryDataSource的数据源来区分不同的JdbcTemplate。
@Bean
public JdbcTemplate primaryJdbcTemplate(@Qualifier("primaryDataSource") DataSource primaryDataSource) {
return new JdbcTemplate(primaryDataSource);
}
@Bean
public JdbcTemplate secondaryJdbcTemplate(@Qualifier("secondaryDataSource") DataSource secondaryDataSource) {
return new JdbcTemplate(secondaryDataSource);
}
}
PrimaryConfig主库配置
import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* @Description:
* @Auther: Wangtianming
* @Date: 2021/12/22 11:12
*/
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef="entityManagerFactoryPrimary",
transactionManagerRef="transactionManagerPrimary",
basePackages= { "com.wtm.demo.repository.primary" }) //设置Repository所在位置
public class PrimaryConfig {
@Resource
@Qualifier("primaryDataSource")
private DataSource primaryDataSource;
@Resource
private JpaProperties jpaProperties;
@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(jpaProperties.getProperties())
.packages("com.wtm.demo.model.primary") //设置实体类所在位置
.persistenceUnit("primaryPersistenceUnit")
.build();
}
@Primary
@Bean(name = "transactionManagerPrimary")
public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
}
}
SecondaryConfig
import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* @Description:
* @Auther: Wangtianming
* @Date: 2021/12/22 11:40
*/
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef="entityManagerFactorySecondary",
transactionManagerRef="transactionManagerSecondary",
basePackages= { "com.wtm.demo.repository.secondary" }) //设置Repository所在位置
public class SecondaryConfig {
@Resource
@Qualifier("secondaryDataSource")
private DataSource secondaryDataSource;
@Resource
private JpaProperties jpaProperties;
@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(jpaProperties.getProperties())
.packages("com.wtm.demo.model.secondary") //设置实体类所在位置
.persistenceUnit("secondaryPersistenceUnit")
.build();
}
@Bean(name = "transactionManagerSecondary")
PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject());
}
}
application.properties配置
spring.datasource.primary.jdbc-url=jdbc:mysql://localhost:3306/test1
spring.datasource.primary.username=root
spring.datasource.primary.password=root
spring.datasource.primary.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.secondary.jdbc-url=jdbc:mysql://localhost:3306/test2
spring.datasource.secondary.username=root
spring.datasource.secondary.password=root
spring.datasource.secondary.driver-class-name=com.mysql.jdbc.Driver
启动类
@SpringBootApplication
public class SpringbootMybatisApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootMybatisApplication.class, args);
}
}
model
Student
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.ToString;
/**
* @Description: 学生信息StringData
* @Auther: Wangtianming
* @Date: 2021/12/18 23:05
*/
@Data
@ApiModel("学生信息StringData")
@Entity
@Table(name = "student")
@ToString(callSuper = true)
public class Student implements Serializable {
@Id
@Column(name = "id", nullable = false)
private Long id;
@ApiModelProperty("用户姓名")
@Column(name = "user_name")
private String userName;
@ApiModelProperty("用户id")
@Column(name = "user_id")
private String userId;
}
Teacher
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.ToString;
/**
* @Description: 老师信息
* @Auther: Wangtianming
* @Date: 2021/12/22 22:22
*/
@Data
@ApiModel("老师信息")
@Entity
@Table(name = "teacher")
@ToString(callSuper = true)
public class Teacher implements Serializable {
@Id
@Column(name = "id", nullable = false)
private Long id;
@ApiModelProperty("用户姓名")
@Column(name = "user_name")
private String userName;
@ApiModelProperty("用户id")
@Column(name = "user_id")
private String userId;
}
Repository
自己封装的BaseRepository
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.NoRepositoryBean;
/**
* @Description:
* @Auther: Wangtianming
* @Date: 2021/12/18 23:31
*/
@NoRepositoryBean
public interface BaseRepository <T, ID> extends JpaRepository<T, ID>, JpaSpecificationExecutor<T> {
}
StudentRepository
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import com.wtm.demo.model.primary.Student;
import com.wtm.demo.repository.BaseRepository;
/**
* @Description: 学生信息
* @Auther: Wangtianming
* @Date: 2021/12/18 23:34
*/
@Repository
public interface StudentRepository extends BaseRepository<Student, Long> {
}
TeacherRepository
import org.springframework.stereotype.Repository;
import com.wtm.demo.model.secondary.Teacher;
import com.wtm.demo.repository.BaseRepository;
/**
* @Description:
* @Auther: Wangtianming
* @Date: 2021/12/22 22:39
*/
@Repository
public interface TeacherRepository extends BaseRepository<Teacher, Long> {
}
Controller
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.wtm.demo.model.primary.Student;
import com.wtm.demo.model.secondary.Teacher;
import com.wtm.demo.repository.primary.StudentRepository;
import com.wtm.demo.repository.secondary.TeacherRepository;
import com.wtm.demo.util.Response;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
/**
* @Description: 测试controller
* @Auther: Wangtianming
* @Date: 2021/12/21 17:21
*/
@Api(tags = "多数据源")
@Slf4j
@RestController
@RequestMapping(path = "/demo/datasourcetest")
public class DataSourceTestController {
@Resource
@Qualifier("primaryJdbcTemplate")
protected JdbcTemplate jdbcTemplate1;
@Resource
@Qualifier("secondaryJdbcTemplate")
protected JdbcTemplate jdbcTemplate2;
@Resource
private StudentRepository studentRepository;
@Resource
private TeacherRepository teacherRepository;
@ApiOperation(value = "primaryJdbcTemplate", notes = "primaryJdbcTemplate")
@GetMapping("/primaryJdbcTemplate")
public Response<List<Map<String, Object>>> primaryJdbcTemplate() {
return Response.ok(jdbcTemplate1.queryForList("select * from student "));
}
@ApiOperation(value = "secondaryJdbcTemplate", notes = "secondaryJdbcTemplate")
@GetMapping("/secondaryJdbcTemplate")
public Response<List<Map<String, Object>>> secondaryJdbcTemplate() {
return Response.ok(jdbcTemplate2.queryForList("select * from teacher "));
}
@ApiOperation(value = "primarySpringData", notes = "primarySpringData")
@GetMapping("/primarySpringData")
public Response<List<Student>> primarySpringData() {
return Response.ok(studentRepository.findAll());
}
@ApiOperation(value = "secondarySpringData", notes = "secondarySpringData")
@GetMapping("/secondarySpringData")
public Response<List<Teacher>> secondarySpringData() {
return Response.ok(teacherRepository.findAll());
}
}
目录
sql脚本
test1库
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`User_Name` varchar(25) DEFAULT NULL,
`User_Id` varchar(25) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8;
BEGIN;
INSERT INTO `student` VALUES (1, '张三01', '20210901');
INSERT INTO `student` VALUES (2, '张三02', '20210902');
INSERT INTO `student` VALUES (3, '张三03', '20210903');
INSERT INTO `student` VALUES (4, '张三04', '20210904');
INSERT INTO `student` VALUES (5, '张三05', '20210905');
INSERT INTO `student` VALUES (6, '张三06', '20210906');
INSERT INTO `student` VALUES (7, '张三07', '20210907');
INSERT INTO `student` VALUES (8, '张三08', '20210908');
INSERT INTO `student` VALUES (9, '张三09', '20210909');
INSERT INTO `student` VALUES (10, '张三10', '20210906');
INSERT INTO `student` VALUES (11, '张三11', '20210911');
INSERT INTO `student` VALUES (12, '张三12', '20210912');
INSERT INTO `student` VALUES (13, '张三13', '20210913');
COMMIT;
SET FOREIGN_KEY_CHECKS = 1;
test2库
DROP TABLE IF EXISTS `teacher`;
CREATE TABLE `teacher` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`User_Name` varchar(25) DEFAULT NULL,
`User_Id` varchar(25) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8;
BEGIN;
INSERT INTO `teacher` VALUES (1, '老师01', '20210901');
INSERT INTO `teacher` VALUES (2, '老师02', '20210902');
INSERT INTO `teacher` VALUES (3, '老师03', '20210903');
INSERT INTO `teacher` VALUES (4, '老师04', '20210904');
INSERT INTO `teacher` VALUES (5, '老师05', '20210905');
INSERT INTO `teacher` VALUES (6, '老师06', '20210906');
INSERT INTO `teacher` VALUES (7, '老师07', '20210907');
INSERT INTO `teacher` VALUES (8, '老师08', '20210908');
INSERT INTO `teacher` VALUES (9, '老师09', '20210909');
INSERT INTO `teacher` VALUES (10, '老师10', '20210906');
INSERT INTO `teacher` VALUES (11, '老师11', '20210911');
INSERT INTO `teacher` VALUES (12, '老师12', '20210912');
INSERT INTO `teacher` VALUES (13, '老师13', '20210913');
COMMIT;
SET FOREIGN_KEY_CHECKS = 1;
参考资料
https://blog.didispace.com/springbootmultidatasource/
Github:https://github.com/dyc87112/SpringBoot-Learning
Gitee:https://gitee.com/didispace/SpringBoot-Learning