vlambda博客
学习文章列表

读书笔记《hands-on-full-stack-development-with-spring-boot-2-0-and-react》使用JPA创建和访问数据库

Chapter 2. Using JPA to Create and Access a Database

本章介绍如何在 Spring Boot 中使用 JPA。我们将使用实体类创建一个数据库。在第一阶段,我们将使用 H2 内存数据库进行开发和演示。 H2 是一个内存 SQL 数据库,非常适合快速开发或演示目的。在第二阶段,我们将从 H2 迁移到使用 MariaDB。本章还介绍了 CRUD 存储库的创建以及数据库表之间的一对多连接。

在本章中,我们将看到以下内容:

  • Basics and benefits of using JPA
  • How to define a database by using entity classes
  • How to create Spring Boot backend with a database

Technical requirements


使用 Spring Boot 需要 Java SDK 版本 8 或更高版本 (http://www.oracle.com/technetwork/java/javase/downloads/index.html)。

MariaDB 安装对于创建数据库应用程序(https://downloads.mariadb.org/)。

Basics of ORM, JPA, and Hibernate

对象-关系映射ORM)是一种< span>允许您从获取和操作 使用面向对象的编程范例的数据库。 ORM 对程序员来说非常好,因为它依赖于面向对象的概念,而不是数据库结构。它还使开发速度更快,并减少了源代码的数量。 ORM 大多独立于数据库并且 开发人员不必担心特定于供应商的SQL 语句。

Java Persistent API (JPA) 提供对象-关系映射< span>适用于 Java 开发人员。 JPA 实体是表示数据库表结构的 Java 类。实体类的字段表示数据库表的columns

Hibernate 是最流行的基于 Java 的 JPA 实现,它在 Spring Boot 中作为默认值使用。 Hibernate 是一个成熟的产品,在大规模应用中被广泛使用。

Creating the entity classes

实体类是一个简单的 Java 类,使用 JPA 的  @Entity 注释进行注释。实体类使用标准的 JavaBean 命名约定并具有适当的 getter setter 方法。类字段具有私有可见性。

JPA 在应用程序初始化时创建一个名为类名的数据库表。如果您想为数据库表使用其他名称,可以使用 @Table 注释。

为了能够使用 JPA 和 H2 数据库,我们必须将以下依赖项添加到 pom.xml 文件中:

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>runtime</scope>
    </dependency>

以下是创建实体类的步骤:

  1. To create an entity class in Spring Boot, we will first create our own package for entities. The package should be created under the root package.
  2. Activate the root package in Eclipse Project Explorer and right-click to show a menu.
  3. From the menu, select New | Package. The following screenshot shows the creation of package for entity classes:
读书笔记《hands-on-full-stack-development-with-spring-boot-2-0-and-react》使用JPA创建和访问数据库

  1. We name our package com.packt.cardatabase.domain:
读书笔记《hands-on-full-stack-development-with-spring-boot-2-0-and-react》使用JPA创建和访问数据库
  1. Next, we create our entity class. Activate a new entity package, right-click, and select New | Class from the menu. Because we are going to create a car database, the name of the entity class is Car. Type Car in the Name field and then press the Finish button:
读书笔记《hands-on-full-stack-development-with-spring-boot-2-0-and-react》使用JPA创建和访问数据库
  1. Open the Car class file in the editor by double-clicking it in the project explorer. First, we have to annotate the class with the @Entity annotation. The Entity annotation is imported from the javax.persistence package:
      package com.packt.cardatabase.domain;

      import javax.persistence.Entity;

      @Entity
      public class Car {

      }

Note

您可以使用 Ctrl + Shift  + O Eclipse IDE 中用于自动导入缺失包的快捷方式。

  1. Next, we add some fields to our class. The entity class fields are mapped to database table columns. The entity class must also contain a unique ID that is used as a primary key in the database:
      package com.packt.cardatabase.domain;

      import javax.persistence.Entity;
      import javax.persistence.GeneratedValue;
      import javax.persistence.GenerationType;
      import javax.persistence.Id;

      @Entity
      public class Car {
        @Id
        @GeneratedValue(strategy=GenerationType.AUTO)
        private long id;
        private String brand, model, color, registerNumber;
        private int year, price;
      }

主键是使用 @Id 注解定义的。  @GeneratedValue注解定义ID由数据库自动生成。我们还可以定义我们的密钥生成策略。类型 AUTO 表示 JPA 提供者为特定数据库选择最佳策略。您还可以通过使用 @Id 注释来注释多个属性来创建复合主键。

数据库列默认按照类字段命名。如果你想使用一些其他的命名约定 你可以使用 @Column注解。使用 @Column 注解,您还可以定义列的长度以及该列是否可以为空。以下代码显示了使用 @Column 注释的示例。有了这个定义,数据库中的列名是 desc ,列的长度是 512 并且不能为空:

@Column(name="desc", nullable=false, length=512)
private String description
  1. 最后,我们将具有属性的 getter、setter 和构造函数添加到实体类中。由于自动 ID 生成,我们的构造函数中不需要 ID 字段。 Car 实体类构造函数源码如下:

Note

Eclipse 提供了 getter、setter 和构造函数的自动添加。在类中激活光标并右键单击。从菜单中,选择 Source | 生成 Getter 和 Setter... or Source | 使用字段生成构造函数...

package com.packt.cardatabase.domain;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Car {
  @Id
  @GeneratedValue(strategy=GenerationType.AUTO)
  private long id;
  private String brand, model, color, registerNumber;
  private int year, price;

  public Car() {}

  public Car(String brand, String model, String color, 
    String registerNumber, int year, int price) {
    super();
    this.brand = brand;
    this.model = model;
    this.color = color;
    this.registerNumber = registerNumber;
    this.year = year;
    this.price = price;
  }

以下是Car实体类getter和setter的源码:

  public String getBrand() {
    return brand;
  }
  public void setBrand(String brand) {
    this.brand = brand;
  }
  public String getModel() {
    return model;
  }
  public void setModel(String model) {
    this.model = model;
  }
  public String getColor() {
    return color;
  }
  public void setColor(String color) {
    this.color = color;
  }
  public String getRegisterNumber() {
    return registerNumber;
  }
  public void setRegisterNumber(String registerNumber) {
    this.registerNumber = registerNumber;
  }
  public int getYear() {
    return year;
  }
  public void setYear(int year) {
    this.year = year;
  }
  public int getPrice() {
    return price;
  }
  public void setPrice(int price) {
    this.price = price;
  } 
}

当我们运行应用程序时,必须在数据库中创建名为 car 的表。为确保这一点,我们将在 application.properties 文件中添加一个新属性。这启用将SQL语句记录到控制台:

spring.jpa.show-sql=true

我们现在可以在运行应用程序时看到创建表的语句:

读书笔记《hands-on-full-stack-development-with-spring-boot-2-0-and-react》使用JPA创建和访问数据库

H2 提供了一个基于 Web 的控制台,可用于探索数据库和执行 SQL 语句。要启用控制台,我们必须将以下行添加到 application.properties 文件中。第一个设置启用 H2 控制台,第二个设置定义我们可以用来访问控制台的端点:

spring.h2.console.enabled=true
spring.h2.console.path=/h2-console

您可以通过使用 Web 浏览器导航到 localhost:8080/h2-console 来访问 H2 控制台。使用 jdbc:h2:mem:testdb 作为 JDBC URL 并保留 Password 字段为空。按 Connect按钮登录控制台:

读书笔记《hands-on-full-stack-development-with-spring-boot-2-0-and-react》使用JPA创建和访问数据库

现在您可以在数据库中看到我们的 car 表。您可能 注意到 注册号在单词之间有一个下划线。这是由于属性 (registerNumber) 的驼峰式命名:

读书笔记《hands-on-full-stack-development-with-spring-boot-2-0-and-react》使用JPA创建和访问数据库

Creating CRUD repositories

Spring Boot Data JPA 为 CRUD 操作提供了一个 CrudRepository 接口。它为我们的实体类提供了 CRUD 功能。

我们现在将在 domain 包中创建我们的 repository,如下所示:

  1. Create a new class called CarRepository in the domain package and modify the file according to the following code snippet:
      package com.packt.cardatabase.domain;

      import org.springframework.data.repository.CrudRepository;

      public interface CarRepository extends CrudRepository <Car, Long> {

      }

我们的 CarRepository 现在扩展了 Spring Boot JPA CrudRepository 接口。 <Car, Long> type 参数定义这是 Car实体类的存储库和类型ID 字段很长。

CrudRepository 提供了多种我们现在可以开始使用的 CRUD 方法。下表列出了最常用的方法:

方法

说明

long count()

返回实体的数量

Iterable<T> findAll()

返回给定类型的所有项目

可选<T> findById(ID Id)

按 id 返回一项

void delete(T entity)

删除实体

void deleteAll()

删除存储库的所有实体

<S 扩展 T>保存(S实体)

保存实体

 

如果该方法只返回一项,则返回 Optional<T> 而不是T。  Optional 类在 Java 8 SE 中被引入。 Optional 是一种单值容器,有值或没有值。通过使用Optional,我们可以防止空指针异常。

  1. Now we are ready to add some demonstration data to our H2 database. For that, we will use the Spring Boot CommandLineRunner. The CommandLineRunner interface allows us to execute additional code before the application has fully started. Therefore, it is a good point to add demo data to your database. CommandLineRunner  is located inside the main class:
      import org.springframework.boot.CommandLineRunner;
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      import org.springframework.context.annotation.Bean;

      @SpringBootApplication
      public class CardatabaseApplication {

        public static void main(String[] args) {
          SpringApplication.run(CardatabaseApplication.class, args);
        }

        @Bean
        CommandLineRunner runner(){
          return args -> {
            // Place your code here
          };
        } 
      }
  1. Next, we have to inject our car repository into the main class into be able to save new car objects to the database. An @Autowired annotation is used to enable dependency injection. The dependency injection allows us to pass dependencies into a object. After we have injected the repository class, we can use the CRUD methods it provides. The following sample code shows how to insert a few cars to the database:
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.boot.CommandLineRunner;
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      import org.springframework.context.annotation.Bean;

      import com.packt.cardatabase.domain.Car;
      import com.packt.cardatabase.domain.CarRepository;

      @SpringBootApplication
      public class CardatabaseApplication {
        @Autowired 
        private CarRepository repository;

        public static void main(String[] args) {
          SpringApplication.run(CardatabaseApplication.class, args);
        }

        @Bean
        CommandLineRunner runner(){
          return args -> {
            // Save demo data to database
            repository.save(new Car("Ford", "Mustang", "Red",
             "ADF-1121", 2017, 59000));
            repository.save(new Car("Nissan", "Leaf", "White",
             "SSJ-3002", 2014, 29000));
            repository.save(new Car("Toyota", "Prius", "Silver",
             "KKO-0212", 2018, 39000));
          };
        } 
      }

Insert 语句可以在应用程序执行后在 Eclipse 控制台中看到:

读书笔记《hands-on-full-stack-development-with-spring-boot-2-0-and-react》使用JPA创建和访问数据库

您还可以使用 H2 控制台从数据库中获取汽车,如以下屏幕截图所示:

读书笔记《hands-on-full-stack-development-with-spring-boot-2-0-and-react》使用JPA创建和访问数据库

您可以在 Spring Data 存储库中定义自己的查询。查询必须以前缀开头,例如  findBy。在前缀之后,您定义查询中使用的 entity 类字段。以下是三个简单查询的示例代码:

import java.util.List;

import org.springframework.data.repository.CrudRepository;

public interface CarRepository extends CrudRepository <Car, Long> {
  // Fetch cars by brand
  List<Car> findByBrand(String brand);

  // Fetch cars by color
  List<Car> findByColor(String color);

  // Fetch cars by year
  List<Car> findByYear(int year);

}

 By 关键字后可以有多个字段,与 AndOr 连接 关键字:

package com.packt.cardatabase.domain;

import java.util.List;

import org.springframework.data.repository.CrudRepository;

public interface CarRepository extends CrudRepository <Car, Long> {
  // Fetch cars by brand and model
  List<Car> findByBrandAndModel(String brand, String model);

  // Fetch cars by brand or color
  List<Car> findByBrandOrColor(String brand, String color); 
}

可以使用查询方法中的 OrderBy关键字对查询进行排序:

package com.packt.cardatabase.domain;

import java.util.List;

import org.springframework.data.repository.CrudRepository;

public interface CarRepository extends CrudRepository <Car, Long> {
  // Fetch cars by brand and sort by year
  List<Car> findByBrandOrderByYearAsc(String brand);
}

您还可以通过@Query 注释使用 SQL 语句创建查询。 以下示例显示了 CrudRepository 中 SQL 查询的用法:

package com.packt.cardatabase.domain;

import java.util.List;

import org.springframework.data.repository.CrudRepository;

public interface CarRepository extends CrudRepository <Car, Long> {
  // Fetch cars by brand using SQL
  @Query("select c from Car c where c.brand = ?1")
  List<Car> findByBrand(String brand);
}

您还可以使用带有 @Query注解的更高级的表达式,例如, like。以下示例显示了 CrudRepositorylike 查询的用法:

package com.packt.cardatabase.domain;

import java.util.List;

import org.springframework.data.repository.CrudRepository;

public interface CarRepository extends CrudRepository <Car, Long> {
  // Fetch cars by brand using SQL
  @Query("select c from Car c where c.brand like %?1")
  List<Car> findByBrandEndsWith(String brand);
}

Spring Data JPA 还提供了PagingAndSortingRepository,它扩展了CrudRepository。它提供了使用分页和排序来获取实体的方法。 如果您要处理大量数据,这是一个不错的选择。 PagingAndSortingRepository 的创建方式与我们对 CrudRepository 所做的类似:

package com.packt.cardatabase.domain;

import org.springframework.data.repository.PagingAndSortingRepository;

public interface CarRepository extends PagingAndSortingRepository<Car, Long> {

}

在这种情况下,您现在拥有存储库提供的两个新的附加方法:

方法

说明

Iterable<T> findAll(排序排序)

返回按给定选项排序的所​​有实体 

页面<T> findAll(Pageable pageable)

根据给定的分页选项返回所有实体

Relationships between tables

接下来,我们创建一个名为 owner 的新表,它具有一对多 relationship 与 car 表。车主可以拥有多辆汽车,但一辆汽车只能拥有一个车主。下面的 UML 图显示了表之间的关系:

读书笔记《hands-on-full-stack-development-with-spring-boot-2-0-and-react》使用JPA创建和访问数据库

以下是创建新表的步骤:

  1. First, we create the Owner entity and repository in the domain package. The Owner entity and repository are created similarly to what we did with the Car class. The following is the source code of the Owner entity class and OwnerRepository:
      // Owner.java

      package com.packt.cardatabase.domain;

      import javax.persistence.Entity;
      import javax.persistence.GeneratedValue;
      import javax.persistence.GenerationType;
      import javax.persistence.Id;

      @Entity
      public class Owner {
        @Id
        @GeneratedValue(strategy=GenerationType.AUTO)
        private long ownerid;
        private String firstname, lastname;

        public Owner() {}

        public Owner(String firstname, String lastname) {
          super();
          this.firstname = firstname;
          this.lastname = lastname;
        }

        public long getOwnerid() {
          return ownerid;
        }
        public void setOwnerid(long ownerid) {
          this.ownerid = ownerid;
        }
        public String getFirstname() {
          return firstname;
        }
        public void setFirstname(String firstname) {
          this.firstname = firstname;
        }
        public String getLastname() {
          return lastname;
        }
        public void setLastname(String lastname) {
          this.lastname = lastname;
        } 
      }
      // OwnerRepository.java

      package com.packt.cardatabase.domain;

      import org.springframework.data.repository.CrudRepository;

      public interface OwnerRepository extends CrudRepository<Owner, Long> 
      {

      }
  1. In this phase, it is good to check that everything is done correctly. Run the project and check that both database tables are created and that there are no errors in the console. The following screenshot shows the console messages when tables are created:
读书笔记《hands-on-full-stack-development-with-spring-boot-2-0-and-react》使用JPA创建和访问数据库

现在,我们的域包包含两个实体类和存储库:

读书笔记《hands-on-full-stack-development-with-spring-boot-2-0-and-react》使用JPA创建和访问数据库

  1. The one-to-many relationship can be added by using the @ManyToOne and @OneToMany annotations. In the car entity class, which contains a foreign key, you will define the relationship with the @ManyToOne annotation. Also, add the getter and setter for the owner field. It is recommended using FetchType.LAZY for all associations. For toMany relationships, that is the default value, but for toOne relationships, you should define it. FetchType defines the strategy for fetching data from the database. The value can be either EAGER or LAZY. In our case, the lazy strategy means that when the owner is fetched from the database, all the cars associated with the owner will be fetched when needed. Eager means that the cars will be fetched immediately with the owner. The following source code shows how to define a one-to-many relationship in the Car class:
      // Car.java

@ManyToOne(fetch = FetchType.LAZY)
      @JoinColumn(name = "owner")
      private Owner owner;

      //Getter and setter
      public Owner getOwner() {
        return owner;
      }

      public void setOwner(Owner owner) {
        this.owner = owner;
      }

在所有者实体站点中,关系是使用 @OneToMany 注释定义的。该字段的类型是 List<Car> 因为车主可能有多辆汽车。还为此添加 getter 和 setter:

      // Owner.java  

      @OneToMany(cascade = CascadeType.ALL, mappedBy="owner")
      private List<Car> cars;

      //Getter and setter
      public List<Car> getCars() {
        return cars;
      }

      public void setCars(List<Car> cars) {
        this.cars = cars;
      }

@OneToMany 注释有两个我们正在使用的属性。  cascade 属性定义了级联如何影响实体。属性设置 ALL 意味着如果所有者被删除,则与该所有者关联的汽车也将被删除。  mappedBy="owner"属性设置告诉我们 Car类有owner字段,也就是外键对于这段关系。

运行项目时,您可以从 console 中看到关系现已创建:

读书笔记《hands-on-full-stack-development-with-spring-boot-2-0-and-react》使用JPA创建和访问数据库
  1. Now, we can add some owners to the database with CommandLineRunner. Let's also modify the Car entity classes constructor and add an owner there:
      // Car.java constructor 

      public Car(String brand, String model, String color,
      String registerNumber, int year, int price, Owner owner) {
        super();
        this.brand = brand;
        this.model = model;
        this.color = color;
        this.registerNumber = registerNumber;
        this.year = year;
        this.price = price;
        this.owner = owner;
      }
  1. We first create two owner objects and save these to the database. For saving the owners, we also have to inject the OwnerRepository into the main class. Then we connect the owners to the cars by using the Car constructor. The following is the source code of the application main class CardatabaseApplication:
      @SpringBootApplication
      public class CardatabaseApplication {
        // Inject repositories
        @Autowired 
        private CarRepository repository;

        @Autowired 
        private OwnerRepository orepository;

        public static void main(String[] args) {
          SpringApplication.run(CardatabaseApplication.class, args);
        }

        @Bean
        CommandLineRunner runner() {
          return args -> {
            // Add owner objects and save these to db
            Owner owner1 = new Owner("John" , "Johnson");
            Owner owner2 = new Owner("Mary" , "Robinson");
            orepository.save(owner1);
            orepository.save(owner2);

            // Add car object with link to owners and save these to db.
            Car car = new Car("Ford", "Mustang", "Red", 
                "ADF-1121", 2017, 59000, owner1);
            repository.save(car);
            car = new Car("Nissan", "Leaf", "White",
                "SSJ-3002", 2014, 29000, owner2);
            repository.save(car);
            car = new Car("Toyota", "Prius", "Silver",
                "KKO-0212", 2018, 39000, owner2);
            repository.save(car);
          };
        } 
      }

如果您现在运行应用程序并从数据库中获取汽车,您可以看到车主现在已链接到汽车:

读书笔记《hands-on-full-stack-development-with-spring-boot-2-0-and-react》使用JPA创建和访问数据库

如果您想改为创建多对多关系,这意味着,实际上,一个车主可以拥有多辆汽车 一辆汽车可以有多个车主,你应该使用 @ManyToMany注解。在我们的示例应用程序中,我们将使用一对多关系,但下面是一个如何将关系更改为多对多的示例。在多对多关系中,建议使用 Set代替List with hibernate:

  1. In the Car entity class many-to-many relationship, define the getters and setters in the following way:
      @ManyToMany(mappedBy = "cars") 
      private Set<Owner> owners; 

      public Set<Owner> getOwners() {
        return owners;
      }

      public void setOwners(Set<Owner> owners) {
        this.owners = owners;
      }

在所有者实体中,定义如下:

      @ManyToMany(cascade = CascadeType.MERGE)
      @JoinTable(name = "car_owner", joinColumns = { @JoinColumn(name =
       "ownerid") }, inverseJoinColumns = { @JoinColumn(name = "id") }) 
      private Set<Car> cars = new HashSet<Car>(0); 

      public Set<Car> getCars() {
        return cars;
      }

      public void setCars(Set<Car> cars) {
        this.cars = cars;
      }
  1. Now, if you run the application, there will be a new join table that is created between the car and owner tables. The join table is defined by using the @JoinTable annotation. With the annotation, we can set the name of the join table and join columns. The following is a screenshot of the database structure when using a many-to-many relationship:
读书笔记《hands-on-full-stack-development-with-spring-boot-2-0-and-react》使用JPA创建和访问数据库

Setting up the MariaDB database

现在,我们将数据库从 H2 切换到 MariaDB。 database 表仍然由 JPA 自动创建。但是在我们运行我们的应用程序之前,我们必须为它创建一个数据库。可以使用 HeidiSQL 创建数据库。打开 HeidiSQL,然后按照以下步骤操作:

  1. Right-click your mouse inside the database list.
  2. Then, select New | Database:
读书笔记《hands-on-full-stack-development-with-spring-boot-2-0-and-react》使用JPA创建和访问数据库

  1. Let's name our database cardb. After you press OK, you should see the new cardb in the database list:
读书笔记《hands-on-full-stack-development-with-spring-boot-2-0-and-react》使用JPA创建和访问数据库
  1. In the application, we add a MariaDB dependency to the pom.xml file and remove the H2 dependency that we don't need any more:
      <dependency>
        <groupId>org.mariadb.jdbc</groupId>
        <artifactId>mariadb-java-client</artifactId>
      </dependency> 
  1. In the application.properties file, you define the database connection. First, you will define the database's url, username, password and database driver class. The spring.jpa.generate-ddl setting defines whether JPA should initialize the database (true/false). The spring.jpa.hibernate.ddl-auto setting defines the behavior of the database initialization. The possible values are none, validate, update, create, and create-drop. Create-drop means that the database is created when an application starts and it is dropped when the application is stopped. Create-drop is also a default value if you don't define any. Create value only creates the database when the application is started. Update value creates the database and updates the schema if it is changed:
      spring.datasource.url=jdbc:mariadb://localhost:3306/cardb
      spring.datasource.username=root
      spring.datasource.password=YOUR_PASSWORD
      spring.datasource.driver-class-name=org.mariadb.jdbc.Driver

      spring.jpa.generate-ddl=true
      spring.jpa.hibernate.ddl-auto=create-drop
  1. Now, after running the application, you should see the tables in MariaDB. The following screenshot shows the HeidiSQL UI after the database has been created. Your application is now ready to be used with MariaDB:
读书笔记《hands-on-full-stack-development-with-spring-boot-2-0-and-react》使用JPA创建和访问数据库

Summary


在本章中,我们使用 JPA 创建了 Spring Boot 应用程序数据库。首先,我们创建了实体类,它们映射到数据库表。然后,我们为实体类创建了 CrudRepository 并为实体提供了 CRUD 操作。之后,我们设法使用 CommandLineRunner 将一些演示数据添加到我们的数据库中。我们还在两个实体之间创建了一对多的关系。本章开头,我们使用了 H2 内存数据库,而最后,我们将数据库切换到了 MariaDB。在下一章中,我们将为后端创建 RESTful Web 服务。

Questions


  1. What are ORM, JPA, and Hibernate?
  2. How can you create an entity class?
  3. How can you create CrudRepository?
  4. How does the CrudRepository provide for your application?
  5. How can you create a one-to-many relationship between tables?
  6. How can you add demo data to a database with Spring Boot?
  7. How can you access the H2 console?
  8. How can you connect your Spring Boot application to MariaDB?