使用Flyway管理Spring Boot数据库迁移

429 阅读3分钟

在靠近用户的地方部署容器

本工程教育(EngEd)计划由科支持。

在全球范围内即时部署容器。Section是经济实惠、简单而强大的。

免费入门

使用Flyway管理Spring Boot数据库迁移

11月5日, 2021

Flyway是一个版本控制系统,用于维护所有应用程序实例的数据库迁移。

在这篇文章中,我们将创建一个学生管理系统,使用Flyway监控数据库迁移。

先决条件

  1. 在你的计算机上安装Java开发工具包
  2. 在电脑上安装MySQL
  3. Spring Boot方面的知识。
  4. 安装有IDE,如Eclipse或Netbeans。

项目设置

  1. 在你的浏览器上,打开spring initializr
  2. project name 作为migration ,将group name 作为com.migrations
  3. 添加Spring Web,Spring Data JPA,Flyway migration, 和MySQL Driver 作为依赖项。
  4. 点击generate ,以压缩文件的形式下载模板项目代码。
  5. 解压缩下载的文件并在你喜欢的代码编辑器中打开该项目。

领域

  1. 创建一个Student 类,并添加下面的代码。
@Entity // Indicates that a class is a database model
@Table(name = "student") // sets the name of the table that the model will be mapped to
@Getter // Creates getters for all the variables in the class
@Setter // Creates setters for all the variables in the class
public class Student {
    @Id // Marks the variable as a primary key 
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(unique = true,name = "email") //sets the database column name and sets it to unique
    private String email;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

    @Column(name = "course")
    private String course;

    @Column(name = "registration_number")
    private String registrationNumber;
}
  • @Entity 注释表明该类是一个持久的Java类。
  • @Id 注释表明被注释的字段是主键。
  • @GeneratedValue 注释用于指定用于主键的生成策略。
  • @Column 注释定义了数据库中映射被注释字段的列。
  • @Getter 注解为 类中的所有字段生成获取器。Student
  • @Setter 注解为 类中的所有字段生成设置器。Student
  • @Table(name = "student") 表示 实体将被映射到数据库中一个名为 的表中。Student student

存储库

创建一个名为StudentRepository 的接口,并在该接口中添加以下代码。

@Repository // Marks the interface as a JPA repository
public interface StudentRepository extends JpaRepository<Student, Integer> {
    Optional<Student> findStudentByEmail(String email); // Custom method to enable quering a student by email address

    void deleteStudentByEmail(String email); //Custom method to eneble deletion of a student by email address
}

JpaRepository 接口接收模型和ID的类型,在我们的例子中,模型是学生,ID类型是Long。

现在我们能够使用所有的JpaRepository方法,包括save(),findOne(),findById(),findAll(),count(),delete(),deleteById() ,而无需提供实现。

  • @Repository 注解将此接口标记为Spring Data JPA仓库。

控制器

@RestController
@RequestMapping("/api/v1/students")
public class StudentController {
    private final StudentRepository studentRepository;

    public StudentController(StudentRepository studentRepository) {
        this.studentRepository = studentRepository;
    }
    //Inserts a student into the database
    @PostMapping
    public ResponseEntity<Student> saveStudent(@RequestBody Student student) {
        return new ResponseEntity<>(studentRepository.save(student), HttpStatus.CREATED);
    }
    //Retrives all students from the database
    @GetMapping
    public ResponseEntity<List<Student>> getStudents() {
        return new ResponseEntity<>(studentRepository.findAll(), HttpStatus.OK);
    }
    //Retrives a single student with the specified email from the database
    @GetMapping("/{email}")
    public ResponseEntity<Student> getStudentByEmail(@PathVariable("email") String email) {
        return new ResponseEntity<>(studentRepository.findStudentByEmail(email).orElseThrow(IllegalStateException::new), HttpStatus.OK);
    }
    //Updates the student with the email passed as path variable
    @PutMapping("/{email}")
    public ResponseEntity<Student> updateStudent(@PathVariable("email") String email, @RequestBody Student student) {
        Student dbStudent = studentRepository.findStudentByEmail(email).orElseThrow(IllegalAccessError::new);
        dbStudent.setCourse(student.getCourse());
        dbStudent.setFirstName(student.getFirstName());
        dbStudent.setLastName(student.getLastName());
        return new ResponseEntity<>(studentRepository.save(dbStudent), HttpStatus.OK);
    }
    //Deletes a student with the email passed as the path variable
    @DeleteMapping("/{email}")
    public ResponseEntity<String> deleteStudent(@PathVariable("email") String email) {
        studentRepository.deleteStudentByEmail(email);
        return new ResponseEntity<>("Student deleted successfully", HttpStatus.NO_CONTENT);
    }
}
  • @RestController 注解标志着这个类是一个可以处理传入的HTTP请求的控制器。
  • @RequestMapping("/api/v1/students") 注解将控制器中的资源端点的基本路径设置为/api/v1/students。
  • @GetMapping 注解表示该函数处理GET请求。
  • @PostMapping 注释表示一个函数处理一个POST请求。
  • @PutMapping 注释表示一个函数处理一个PUT请求。
  • @DeleteMapping 注释表示一个函数处理一个DELETE请求。

配置

在资源文件夹中,将下面的代码片段添加到application.properties 文件中。

#  Sets the database URL
spring.datasource.url = jdbc:mysql://localhost:3306/flyway_migrations?useSSL=false
# Sets the database username
spring.datasource.username = mysql_username
# Sets the database password
spring.datasource.password = mysql_password
# Sets the database dialect to use, for example we use MySQL5InnoDBDialect since we are using MySQL
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
# Sets the database update strategy, we are using validate since we want to validate if the update is correct the changes made to database
spring.jpa.hibernate.ddl-auto = validate

在资源文件夹中,创建一个名为db 的新文件夹。然后在db 目录下生成另一个名为migrations 的文件夹。

接下来,创建一个SQL文件名为V1__init.sql ,并添加下面的代码片断。

CREATE TABLE student
(
    student_id                  bigint(20) not null AUTO_INCREMENT,
    first_name          varchar(50) not null,
    last_name           varchar(50) not null,
    email               varchar(50) not null,
    course              varchar(50) not null,
    registration_number varchar(50)  not null,
    primary key (student_id),
    unique key UK_email(email)
)

上述代码在数据库中创建了student 表。

你不应该使用自动数据库表创建工具,因为它不能产生优化的SQL代码。

数据库设置

通过终端创建一个名为fly_migrations 的数据库,如下图所示,或通过PHPMyAdmin的Web界面。

elvis@elvis:~$ sudo mysql
[sudo] password for elvis: 
mysql> create database flyway_migrations;
Query OK, 1 row affected (0.01 sec)

mysql> 

通过执行命令./mvnw spring-boot:run ,运行应用程序。然后,在命令行上,输入sudo mysql ,启动MySQL CLI。

接下来,执行命令select * from flyway_schema_history ,如下图所示。

first migration

当我们重新运行应用程序并检查学生的表格时,我们应该看到以下结果。

通过Flyway迁移插入数据

在上面创建的db 文件夹中,创建一个名为V2_data.sql 的新的SQL文件,并添加下面的SQL脚本。

insert into student(email, first_name, last_name, course, registration_number)
values ("test@outlook.com", "test1", "tester1", "Computer science", "ABA1112");
insert intbooto student(email, first_name, last_name, course, registration_number)
values ("tester2@outlook.com", "test2", "tester2", "Computer science", "ABA7712");

当我们检查Flyway migrations表时,我们看到数据被成功插入了。

测试

Second migration

数据被插入到了表中,如下图所示。

Result

现在我们已经创建了一个表,并向数据库中插入了数据,让我们执行下面的命令来回滚上次的迁移。

$ ./flyway undo

上面的命令将删除从第二个脚本中插入到数据库中的数据。

总结

在本教程中,我们已经学会了如何使用Flyway迁移工具管理Spring Boot数据库迁移。

因此,你可以利用这些知识来制作更多高质量的应用程序。


同行评审贡献者:。Miller Juma

类似文章

[

How to Create a Reusable React Form component Hero Image

语言

如何创建一个可重复使用的React表单组件

阅读更多

](www.section.io/engineering…

Building a payroll system with next.js Hero Image

语言, Node.js

用Next.js构建一个薪资系统

阅读更多

](www.section.io/engineering…

Creating and Utilizing Decorators in Django example image

架构

在Django中创建和使用装饰器

阅读更多

](www.section.io/engineering…)