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

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 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
目录
相关文章
|
8天前
|
SQL 监控 druid
springboot-druid数据源的配置方式及配置后台监控-自定义和导入stater(推荐-简单方便使用)两种方式配置druid数据源
这篇文章介绍了如何在Spring Boot项目中配置和监控Druid数据源,包括自定义配置和使用Spring Boot Starter两种方法。
|
21天前
|
XML Java 数据格式
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
Spring 第二节内容补充 关于Bean配置的更多内容和细节 万字详解!
119 18
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
|
9天前
|
前端开发 Java Spring
关于spring mvc 的 addPathPatterns 拦截配置常见问题
关于spring mvc 的 addPathPatterns 拦截配置常见问题
消息中间件 缓存 监控
81 0
|
22天前
|
Java 数据库连接 Maven
Spring基础1——Spring(配置开发版),IOC和DI
spring介绍、入门案例、控制反转IOC、IOC容器、Bean、依赖注入DI
Spring基础1——Spring(配置开发版),IOC和DI
|
1月前
|
IDE Java 开发工具
还在为繁琐的配置头疼吗?一文教你如何用 Spring Boot 快速启动,让开发效率飙升,从此告别加班——打造你的首个轻量级应用!
【9月更文挑战第2天】Spring Boot 是一款基于 Spring 框架的简化开发工具包,采用“约定优于配置”的原则,帮助开发者快速创建独立的生产级应用程序。本文将指导您完成首个 Spring Boot 项目的搭建过程,包括环境配置、项目初始化、添加依赖、编写控制器及运行应用。首先需确保 JDK 版本不低于 8,并安装支持 Spring Boot 的现代 IDE,如 IntelliJ IDEA 或 Eclipse。
87 5
|
2月前
|
Java 微服务 Spring
Spring Cloud全解析:配置中心之解决configserver单点问题
但是如果该configserver挂掉了,那就无法获取最新的配置了,微服务就出现了configserver的单点问题,那么如何避免configserver单点呢?
|
2月前
|
运维 Java Nacos
Spring Cloud应用框架:Nacos作为服务注册中心和配置中心
Spring Cloud应用框架:Nacos作为服务注册中心和配置中心
|
2月前
|
安全 前端开发 Java
Web端系统开发解决跨域问题——以Java SpringBoot框架配置Cors为例
在Web安全上下文中,源(Origin)是指一个URL的协议、域名和端口号的组合。这三个部分共同定义了资源的来源,浏览器会根据这些信息来判断两个资源是否属于同一源。例如,https://www.example.com:443和http://www.example.com虽然域名相同,但由于协议和端口号不同,它们被视为不同的源。同源(Same-Origin)是指两个URL的协议、域名和端口号完全相同。只有当这些条件都满足时,浏览器才认为这两个资源来自同一源,从而允许它们之间的交互操作。
Web端系统开发解决跨域问题——以Java SpringBoot框架配置Cors为例
|
2月前
|
Java Spring 开发者
解锁 Spring Boot 自动化配置的黑科技:带你走进一键配置的高效开发新时代,再也不怕繁琐设置!
【8月更文挑战第31天】Spring Boot 的自动化配置机制极大简化了开发流程,使开发者能专注业务逻辑。通过 `@SpringBootApplication` 注解组合,特别是 `@EnableAutoConfiguration`,Spring Boot 可自动激活所需配置。例如,添加 JPA 依赖后,只需在 `application.properties` 配置数据库信息,即可自动完成 JPA 和数据源设置。这一机制基于多种条件注解(如 `@ConditionalOnClass`)实现智能配置。深入理解该机制有助于提升开发效率并更好地解决问题。
49 0
下一篇
无影云桌面