SpringBoot-17-Spring-Data-JPA的多数据源配置

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: SpringBoot-17-Spring-Data-JPA的多数据源配置

SpringBoot-17-Spring-Data-JPA的多数据源配置

在这之前我们以及介绍了


2.png


看过Jbdc多数据源配置的配置的都知道,既然我们现在介绍了Spring-Data-Jpa的操作了,那么现在我们就要介绍Spring-Data-Jpa的多数据操作了。


创建两个数据源的实体表

Student表的创建

create table `student`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '学生姓名',
 `sex` enum ('男', '女') DEFAULT '男' COMMENT '性别默认男',
 `age` tinyint unsigned default 1 comment '年龄',
  `mobile` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '注册手机号',
  `email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '注册邮箱',
  `create_date` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
  `update_date` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
 `is_enabled` int(2) NULL DEFAULT 1 COMMENT '帐户是否可用(1 可用,0 删除用户)',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `name`(`name`) USING BTREE,
  UNIQUE INDEX `mobile`(`mobile`) USING BTREE,
  UNIQUE INDEX `email`(`email`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '学生表' ROW_FORMAT = Dynamic;



Teacher表的创建

create table `teacher`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '教师姓名',
 `sex` enum ('男', '女') DEFAULT '男' COMMENT '性别默认男',
 `age` tinyint unsigned default 1 comment '年龄',
   `course` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '上课科目',
  `mobile` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '手机号',
  `email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '邮箱',
  `create_date` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
  `update_date` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
 `is_enabled` int(2) NULL DEFAULT 1 COMMENT '帐户是否可用(1 可用,0 删除用户)',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `name`(`name`) USING BTREE,
  UNIQUE INDEX `mobile`(`mobile`) USING BTREE,
  UNIQUE INDEX `email`(`email`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '教师表' ROW_FORMAT = Dynamic;



创建实体类

创建Student对应的实体类

@Table(name="student")
@Entity
@Data
public class Student {
    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String sex;
    private int age;
    private String email;
    private String mobile;
    private int isEnabled;
    private Date createDate;
    private Date updateDate;
}


创建teacher表对应的实体类

@Table(name="teacher")
@Entity
@Data
public class Teacher {
    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String sex;
    private String course;
    private int age;
    private String email;
    private String mobile;
    private int isEnabled;
    private Date createDate;
    private Date updateDate;
}


配置application.yml为多数据源配置

配置2个数据源,student数据源:mybatis数据库,teacher数据源:mysql数据库

server:
  port: 8899
spring:
  datasource:
    student:
      jdbc-url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=utf-8&useSSL=false
      username: root
      password: root
      driver-class-name: com.mysql.cj.jdbc.Driver
    teacher:
      jdbc-url: jdbc:mysql://localhost:3306/mysql?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=utf-8&useSSL=false
      username: root
      password: root
      driver-class-name: com.mysql.cj.jdbc.Driver
  jpa:
    database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
    show-sql: true
    database: mysql



持久化接口

创建Student表对应的接口层StudentService

public interface StudentService extends PagingAndSortingRepository<Student, Long> {
    /**
     * 获取所有在校学生信息
     * @return
     */
    @Query("from Student s where s.isEnabled=1")
    Slice<Student> getAllSutdents(Pageable pageable);
}



创建Teacher表对应的接口层TeacherService

public interface TeacherService extends PagingAndSortingRepository<Teacher, Long> {
    /**
     * 获取所有在校老师信息
     * @return
     */
    @Query("from Teacher s where s.isEnabled=1")
    Slice<Teacher> getAllTeachers(Pageable pageable);
}


JPA数据源配置


配置JPA的数据源,需要配置:

  • DataSource数据源
  • EntityManager 实体管理器
  • EntityManagerFactoryBean 实体管理器工厂
  • PlatformTransactionManager 事务管理器



student数据源配置如下:

import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
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;
import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
import java.util.Map;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef="entityManagerFactoryStudent",
        transactionManagerRef="transactionManagerStudent",
        basePackages= {"com.learn.springboot.entity.student"}) //换成你自己的Repository所在位置
public class JPAStudentConfig {
    @Resource
    private JpaProperties jpaProperties;
    @Resource
    private HibernateProperties hibernateProperties;
    /**
     * 主数据源默认使用Student
     * @return
     */
    @Primary
    @Bean(name = "studentDataSource")
    @ConfigurationProperties(prefix="spring.datasource.student")  //使用application.yml的primary数据源配置
    public DataSource studentDataSource() {
        return DataSourceBuilder.create().build();
    }
    /**
     * 数据管理器
     * @param builder
     * @return
     */
    @Primary
    @Bean(name = "entityManagerStudent")        //primary实体管理器
    public EntityManager entityManagerStudent(EntityManagerFactoryBuilder builder) {
        return entityManagerFactoryStudent(builder).getObject().createEntityManager();
    }
    /**
     * 实体惯例工厂
     * @param builder
     * @return
     */
    @Primary
    @Bean(name = "entityManagerFactoryStudent")    //primary实体工厂
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryStudent (EntityManagerFactoryBuilder builder) {
        Map<String,Object> properties =
                hibernateProperties.determineHibernateProperties(
                        jpaProperties.getProperties(),
                        new HibernateSettings());
        return builder.dataSource(studentDataSource())
                .properties(properties)
                //换成数据表对应实体类所在包
                .packages("com.learn.springboot.entity.student")
                .persistenceUnit("primaryPersistenceUnit")
                .build();
    }
    /**
     * 事务管理器
     * @param builder
     * @return
     */
    @Primary
    @Bean(name = "transactionManagerStudent")         //primary事务管理器
    public PlatformTransactionManager transactionManagerStudent(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(entityManagerFactoryStudent(builder).getObject());
    }
}



teacher-数据源配置如下:

HibernateProperties hibernateProperties;
    @Bean(name = "teacherDataSource")
    //使用application.yml的teacher数据源配置
    @ConfigurationProperties(prefix="spring.datasource.teacher")  
    public DataSource teacherDataSource() {
        return DataSourceBuilder.create().build();
    }
    //teacher实体管理器
    @Bean(name = "entityManagerTeacher")     
    public EntityManager entityManagerTeacher(EntityManagerFactoryBuilder builder) {
        return entityManagerFactoryTeacher(builder).getObject().createEntityManager();
    }
    @Bean(name = "entityManagerFactoryTeacher")
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryTeacher (EntityManagerFactoryBuilder builder) {
        Map<String,Object> properties =
                hibernateProperties.determineHibernateProperties(
                        jpaProperties.getProperties(),
                        new HibernateSettings());
        return builder
                .dataSource(teacherDataSource())
                .properties(properties)
                //换成数据表对应实体类所在包
                .packages("com.learn.springboot.entity.teacher")
                .persistenceUnit("secondaryPersistenceUnit")
                .build();
    }
    @Bean(name = "transactionManagerTeacher")
    PlatformTransactionManager transactionManagerTeacher(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(entityManagerFactoryTeacher(builder).getObject());
    }
}


控制层的实现

Student控制层的实现

@Slf4j
@RestController
@RequestMapping("/student")
public class StudentController {
    @Autowired
    private StudentService studentService;
    @GetMapping("getallstudents")
    public Slice<Student> getAllSutdents(PageNumber pageNumber){
        if(pageNumber.getNumber()==0){
            pageNumber =new PageNumber();
            pageNumber.setNumber(0);
            pageNumber.setSize(10);
        }
        //分页查询
        Slice<Student> createDate = studentService.getAllSutdents(PageRequest.of(pageNumber.getNumber(), pageNumber.getSize(), Sort.by("createDate")));
        return createDate;
    }
    /**
     * 保存数据
     * @param student
     * @return
     */
    @PostMapping("create")
    public Student saveStudent(@RequestBody Student student) {
        //保存一个对象到数据库,insert
        studentService.save(student);
        return  student;
    }
    @GetMapping("/{id}")
    public Student getSutdentInfo(@PathVariable("id") Long id) {
        Optional<Student> optional = studentService.findById(id);
        return optional.orElseGet(Student::new);
    }
    @GetMapping("/delete/{id}")
    public void deleteSutdent(@PathVariable("id") Long id) {
        //根据id删除1条数据库记录
        studentService.deleteById(id);
    }
    @PostMapping("update")
    public @ResponseBody
    Student updatSutdent(@RequestBody Student student) {
        Optional<Student> optional = studentService.findById(student.getId());
        Student stu = optional.orElseGet(Student::new);
        stu.setEmail(student.getEmail());
        stu.setMobile(student.getEmail());
        stu.setAge(student.getAge());
        stu.setSex(student.getSex());
        stu.setName(student.getName());
        stu.setUpdateDate(new Date());
        //保存一个对象到数据库,insert
        Student save = studentService.save(student);
        return  save;
    }
    @GetMapping("getall")
    public Page<Student> getAll(PageNumber pageNumber) {
        if(pageNumber.getNumber()==0){
            pageNumber =new PageNumber();
            pageNumber.setNumber(0);
            pageNumber.setSize(10);
        }
        Page<Student> studentList =studentService.findAll(PageRequest.of(pageNumber.getNumber(),pageNumber.getSize()));
        //查询student表的所有数据
        return studentList;
    }
    @GetMapping("getAllSecond")
    public Page<Student> getAllSecond(PageNumber pageNumber) {
        if(pageNumber.getNumber()==0){
            pageNumber =new PageNumber();
            pageNumber.setNumber(0);
            pageNumber.setSize(10);
        }
        Page<Student> studentList =studentService.findAll(PageRequest.of(pageNumber.getNumber(),pageNumber.getSize()));
        //查询student表的所有数据
        return studentList;
    }
}@Slf4j
@RestController
@RequestMapping("/student")
public class StudentController {
    @Autowired
    private StudentPrimayService studentService;
    @Autowired
    private StudentSecondaryService studentSecondaryService;
    @GetMapping("getallstudents")
    public Slice<StudentPrimay> getAllSutdents(PageNumber pageNumber){
        if(pageNumber.getNumber()==0){
            pageNumber =new PageNumber();
            pageNumber.setNumber(0);
            pageNumber.setSize(10);
        }
        //分页查询
        Slice<StudentPrimay> createDate = studentService.getAllSutdents(PageRequest.of(pageNumber.getNumber(), pageNumber.getSize(), Sort.by("createDate")));
        return createDate;
    }
    /**
     * 保存数据
     * @param student
     * @return
     */
    @PostMapping("create")
    public StudentPrimay saveStudent(@RequestBody StudentPrimay student) {
        //保存一个对象到数据库,insert
        studentService.save(student);
        return  student;
    }
    @GetMapping("/{id}")
    public StudentPrimay getSutdentInfo(@PathVariable("id") Long id) {
        Optional<StudentPrimay> optional = studentService.findById(id);
        return optional.orElseGet(StudentPrimay::new);
    }
    @GetMapping("/delete/{id}")
    public void deleteSutdent(@PathVariable("id") Long id) {
        //根据id删除1条数据库记录
        studentService.deleteById(id);
    }
    @PostMapping("update")
    public @ResponseBody StudentPrimay updatSutdent(@RequestBody StudentPrimay student) {
        Optional<StudentPrimay> optional = studentService.findById(student.getId());
        StudentPrimay stu = optional.orElseGet(StudentPrimay::new);
        stu.setEmail(student.getEmail());
        stu.setMobile(student.getEmail());
        stu.setAge(student.getAge());
        stu.setSex(student.getSex());
        stu.setName(student.getName());
        stu.setUpdateDate(new Date());
        //保存一个对象到数据库,insert
        StudentPrimay save = studentService.save(student);
        return  save;
    }
    @GetMapping("getall")
    public Page<StudentPrimay> getAll(PageNumber pageNumber) {
        if(pageNumber.getNumber()==0){
            pageNumber =new PageNumber();
            pageNumber.setNumber(0);
            pageNumber.setSize(10);
        }
        Page<StudentPrimay> studentList =studentService.findAll(PageRequest.of(pageNumber.getNumber(),pageNumber.getSize()));
        //查询article表的所有数据
        return studentList;
    }
    @GetMapping("getAllSecond")
    public Page<StudentSecondary> getAllSecond(PageNumber pageNumber) {
        if(pageNumber.getNumber()==0){
            pageNumber =new PageNumber();
            pageNumber.setNumber(0);
            pageNumber.setSize(10);
        }
        Page<StudentSecondary> studentList =studentSecondaryService.findAll(PageRequest.of(pageNumber.getNumber(),pageNumber.getSize()));
        //查询article表的所有数据
        return studentList;
    }
}


Teacher控制层的实现

@Slf4j
@RestController
@RequestMapping("/teacher")
public class TeacherController {
    @Autowired
    private TeacherService teacherService;
    @GetMapping("allteachers")
    public Slice<Teacher> getAllTeachers(PageNumber pageNumber){
        if(pageNumber.getNumber()==0){
            pageNumber =new PageNumber();
            pageNumber.setNumber(0);
            pageNumber.setSize(10);
        }
        //分页查询
        Slice<Teacher> createDate = teacherService.getAllTeachers(PageRequest.of(pageNumber.getNumber(), pageNumber.getSize(), Sort.by("createDate")));
        return createDate;
    }
    /**
     * 保存数据
     * @param teacher
     * @return
     */
    @PostMapping("create")
    public Teacher saveTeacher(@RequestBody Teacher teacher) {
        //保存一个对象到数据库,insert
        teacherService.save(teacher);
        return  teacher;
    }
    @GetMapping("/{id}")
    public Teacher getTeacherInfo(@PathVariable("id") Long id) {
        Optional<Teacher> optional = teacherService.findById(id);
        return optional.orElseGet(Teacher::new);
    }
    @GetMapping("/delete/{id}")
    public void deleteTeacher(@PathVariable("id") Long id) {
        //根据id删除1条数据库记录
        teacherService.deleteById(id);
    }
    @PostMapping("update")
    public @ResponseBody
    Teacher updatTeacher(@RequestBody Teacher teacher) {
        Optional<Teacher> optional = teacherService.findById(teacher.getId());
        Teacher tea = optional.orElseGet(Teacher::new);
        tea.setEmail(teacher.getEmail());
        tea.setCourse(teacher.getCourse());
        tea.setMobile(teacher.getEmail());
        tea.setAge(teacher.getAge());
        tea.setSex(teacher.getSex());
        tea.setName(teacher.getName());
        tea.setUpdateDate(new Date());
        //保存一个对象到数据库,insert
        Teacher save = teacherService.save(tea);
        return  save;
    }
    @GetMapping("getall")
    public Page<Teacher> getAll(PageNumber pageNumber) {
        if(pageNumber.getNumber()==0){
            pageNumber =new PageNumber();
            pageNumber.setNumber(0);
            pageNumber.setSize(10);
        }
        Page<Teacher> teachers =teacherService.findAll(PageRequest.of(pageNumber.getNumber(),pageNumber.getSize()));
        //查询teacher表的所有数据
        return teachers;
    }
    @GetMapping("getAllTeacher")
    public Page<Teacher> getAllTeacher(PageNumber pageNumber) {
        if(pageNumber.getNumber()==0){
            pageNumber =new PageNumber();
            pageNumber.setNumber(0);
            pageNumber.setSize(10);
        }
        Page<Teacher> teachers =teacherService.findAll(PageRequest.of(pageNumber.getNumber(),pageNumber.getSize()));
        //查询teacher表的所有数据
        return teachers;
    }
}



测试


使用postman分别测试


http://localhost:8899/teacher/create Post方法


http://localhost:8899/teacher/update Post方法


http://localhost:8899/student/getallstudents Get方法


分别测试了student和teacher的方法以及Get和Post方法。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
24天前
|
Java 开发者 微服务
手写模拟Spring Boot自动配置功能
【11月更文挑战第19天】随着微服务架构的兴起,Spring Boot作为一种快速开发框架,因其简化了Spring应用的初始搭建和开发过程,受到了广大开发者的青睐。自动配置作为Spring Boot的核心特性之一,大大减少了手动配置的工作量,提高了开发效率。
46 0
|
2月前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
52 4
|
2月前
|
Java API 数据库
Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐
本文通过在线图书管理系统案例,详细介绍如何使用Spring Boot构建RESTful API。从项目基础环境搭建、实体类与数据访问层定义,到业务逻辑实现和控制器编写,逐步展示了Spring Boot的简洁配置和强大功能。最后,通过Postman测试API,并介绍了如何添加安全性和异常处理,确保API的稳定性和安全性。
41 0
|
2月前
|
Java API Spring
在 Spring 配置文件中配置 Filter 的步骤
【10月更文挑战第21天】在 Spring 配置文件中配置 Filter 是实现请求过滤的重要手段。通过合理的配置,可以灵活地对请求进行处理,满足各种应用需求。还可以根据具体的项目要求和实际情况,进一步深入研究和优化 Filter 的配置,以提高应用的性能和安全性。
|
28天前
|
缓存 IDE Java
SpringBoot入门(7)- 配置热部署devtools工具
SpringBoot入门(7)- 配置热部署devtools工具
39 2
 SpringBoot入门(7)- 配置热部署devtools工具
|
18天前
|
存储 前端开发 JavaScript
springboot中路径默认配置与重定向/转发所存在的域对象
Spring Boot 提供了简便的路径默认配置和强大的重定向/转发机制,通过合理使用这些功能,可以实现灵活的请求处理和数据传递。理解并掌握不同域对象的生命周期和使用场景,是构建高效、健壮 Web 应用的关键。通过上述详细介绍和示例,相信读者能够更好地应用这些知识,优化自己的 Spring Boot 应用。
24 3
|
27天前
|
Java 数据库连接
SpringBoot配置多数据源实战
第四届光学与机器视觉国际学术会议(ICOMV 2025) 2025 4th International Conference on Optics and Machine Vision
51 8
|
24天前
|
Java 数据库连接 数据库
springboot启动配置文件-bootstrap.yml常用基本配置
以上是一些常用的基本配置项,在实际应用中可能会根据需求有所变化。通过合理配置 `bootstrap.yml`文件,可以确保应用程序在启动阶段加载正确的配置,并顺利启动运行。
55 2
|
1月前
|
Java Spring
[Spring]aop的配置与使用
本文介绍了AOP(面向切面编程)的基本概念和核心思想。AOP是Spring框架的核心功能之一,通过动态代理在不修改原代码的情况下注入新功能。文章详细解释了连接点、切入点、通知、切面等关键概念,并列举了前置通知、后置通知、最终通知、异常通知和环绕通知五种通知类型。
30 1
|
1月前
|
Java Spring 容器
SpringBoot读取配置文件的6种方式,包括:通过Environment、@PropertySource、@ConfigurationProperties、@Value读取配置信息
SpringBoot读取配置文件的6种方式,包括:通过Environment、@PropertySource、@ConfigurationProperties、@Value读取配置信息
68 3