Spring Boot集成H2数据库

x33g5p2x  于2022-09-17 转载在 Spring  
字(9.3k)|赞(0)|评价(0)|浏览(810)

在这篇文章中,我们将看到如何使用Spring Boot与H2数据库。就像其他数据库一样,在Spring Boot生态系统中对它有充分的内在支持。

Spring Boot与H2数据库

H2数据库是一个比较新的、开源的、用Java编写的内存关系型数据库管理系统。就像其他内存数据库一样,H2数据库依靠系统内存来加载和保存数据,而不是物理磁盘存储。它是一个嵌入式数据库,我们可以在我们的java应用程序中使用,或以客户-服务器模式运行。内存数据库非常快,因为数据访问是从系统内存中完成的,而不是磁盘存储。它们是不稳定的,也就是说,在应用程序重新启动的情况下,所有的数据都会丢失。

我们可以将H2这样的内存数据库用于POCs,并在开发阶段通过模式变化进行迭代,而不对MYSQL这样的实际持久性数据库进行修改。另一个使用H2的案例是在我们应用程序的单元测试期间。H2数据库不能用于生产应用。

1. 用Spring Boot配置H2数据库

要使用Spring Boot和H2数据库,我们需要在我们的应用程序中配置H2数据库,如果我们使用Spring,配置是非常直接的。如果使用maven作为构建工具,我们首先需要在pom.xml中添加H2的必要依赖。在项目中加入所需的依赖后,我们需要在application.propertiesapplication.yaml文件中加入以下属性。这样,通过在属性文件中添加所需的属性,我们可以连接到任何数据库。以下是我们用Sprig Boot设置H2数据库时的一些重要属性。

**数据源URL:为了建立数据库连接,Java的Datasource接口使用一个URL和一些证书。在URL中,我们需要提供内存数据库的名称和模式。由于我们使用的是H2数据库,'mem'是内存数据库的名称,'testdb'**是模式的名称,由H2默认提供。
**驱动类名称:**H2是一个java数据库,我们可以通过使用JDBC与它进行交互。为此,我们首先需要注册JDBC数据库驱动。这里我们提供驱动类的名称。  
**用户名:**默认情况下,提供的用户名是'sa'。我们可以通过在application.properties文件中设置适当的名称来覆盖这个值。
**password:**默认情况下,提供的密码是空的。我们可以通过在application.properties文件中设置适当的密码来覆盖这个值。

2. 依赖性

要使用Spring Boot与H2数据库,我们需要添加所需的H2依赖。提供的范围是运行时,因为我们要在运行单元测试案例时使用H2。如果我们使用maven作为构建工具,在pom.xml中添加以下依赖。

<dependency>
   <groupId>com.h2database</groupId>
   <artifactId>h2</artifactId>
   <scope>runtime</scope>
</dependency>

或者,我们也可以使用下面的gradle脚本。

dependencies {
    compile group: 'commons-collections', name: 'commons-collections', version: '3.2'
    testCompile group: 'junit', name: 'junit', version: '4.+'
    compile group: 'com.h2database', name: 'h2', version: '1.3.148'
}

3. 用Spring Boot配置H2数据库

为了使我们的应用程序能够连接到数据库,我们需要添加以下配置。默认情况下,Spring将我们的应用程序配置为连接到像H2这样的内存数据库,用户的默认值为 "sa",密码为空。我们可以在application.propertiesapplication.yaml文件中覆盖这些值。

spring.datasource.url=jdbc:h2:mem:javadevjournal 
spring.datasource.driverClassName=org.h2.Driver 
spring.datasource.username=sa 
spring.datasource.password=pass 
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect

或者,我们可以使用application.yaml文件进行配置。

spring: 
   datasource: 
      url: jdbc:h2:mem: javadevjournal
      username: sa 
      password: pass 
      driverClassName: org.h2.Driver 
   jpa: 
      spring.jpa.database-platform: org.hibernate.dialect.H2Dialect

H2数据库支持两种持久性模式。内存中和基于文件的存储。添加上述属性将提供一个内存中的H2实现,它是易失性的,也就是说,当应用程序重新启动时,数据会丢失。

如果我们需要一个基于文件的存储,那么我们可以在application.propertiesapplication.yaml文件中更新spring.datasource.url属性。

spring.datasource.url=jdbc:h2:file:/data/filename

我们也可以使用yaml配置来实现。

spring:
  datasource:
    url:  jdbc:h2:file:/data/filename

4. 处理数据库操作

让我们看看我们的Spring Boot与H2数据库应用程序的一些数据库操作。在Spring Boot项目中用H2执行数据库操作,如CRUD,与其他SQL数据库相似。

4.1. 初始化数据源

要使用像MYSQL这样的数据库,我们首先需要安装它们,然后创建模式,再创建表并填充数据。当使用内存数据库时,我们不需要单独安装数据库。数据库和模式存在于我们正在运行的应用程序的内存中。数据库模式是根据提供给应用程序的配置来创建的。我们可以提供SQL脚本来初始化数据库,其中可以包含创建表和插入表的查询。如果我们有一个spring boot项目和JPA依赖,那么,通过查看存在的实体,整个数据库将在应用程序启动时被创建。

为了在应用程序启动时填充表中的数据,我们可以在src/main/resources文件夹中添加data.sql文件。默认情况下,Spring boot会自动选择这个文件,并针对我们的嵌入式H2数据库实例运行它。我们可以通过将spring.sql.init.mode设置为never来改变这一默认行为。

INSERT INTO employee (id, name, salary) VALUES (1, 'Amy', 3500.0);
INSERT INTO employee (id, name, salary) VALUES (2, 'Jake', 4000.0);
INSERT INTO employee (id, name, salary) VALUES (3, 'Charles', 3000.0);
INSERT INTO employee (id, name, salary) VALUES (4, 'Terry', 5500.0);
INSERT INTO employee (id, name, salary) VALUES (5, 'Rosa', 5000.0);
4.2. 使用Hibernate

data.sql脚本默认在hibernate初始化之前执行。  由于我们每次都要重新创建由Hibernate生成的模式,所以我们需要多设置一个属性。

spring.jpa.defer-datasource-initialization=true

通过设置这个属性,data.sql将在hibernate完成模式生成后被执行。此外,我们还可以使用schema.sql来覆盖hibernate在使用data.sql生成数据之前的模式。

5. 使用H2数据库构建Spring Boot应用程序

让我们使用Spring Boot与H2数据库建立一个应用程序。我们将创建一个雇员实体,并在REST应用程序中执行CRUD操作。我们使用spring initializr来准备项目结构。

下面是我们将项目结构导入到所选择的IDE后的样子。

这就是完整的pom.xml的样子。请注意,它可以根据你的项目所使用的依赖关系而改变。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>2.6.2</version>
      <relativePath />
      <!-- lookup parent from repository -->
   </parent>
   <groupId>com.javadevjournal</groupId>
   <artifactId>spring-boot-h2</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <name>spring-boot-h2</name>
   <description>Spring Boot project for H2 illustration</description>
   <properties>
      <java.version>1.8</java.version>
   </properties>
   <dependencies>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-data-jpa</artifactId>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
      <dependency>
         <groupId>com.h2database</groupId>
         <artifactId>h2</artifactId>
         <scope>runtime</scope>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-test</artifactId>
         <scope>test</scope>
      </dependency>
   </dependencies>
   <build>
      <plugins>
         <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
               <excludes>
                  <exclude>
                     <groupId>org.projectlombok</groupId>
                     <artifactId>lombok</artifactId>
                  </exclude>
               </excludes>
            </configuration>
         </plugin>
      </plugins>
   </build>
</project>
5.1. 定义实体模型

首先,我们将创建Employee实体类,用e1d29d1来告诉JPA,这将被映射到数据库中的一个表。

package com.javadevjournal.springbooth2.model;

import javax.persistence.*;

@Entity
@Table(name = "EMPLOYEE")
public class Employee {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Integer id;
    String name;
    Double salary;

    public Integer getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Double getSalary() {
        return salary;
    }

    public void setSalary(Double salary) {
        this.salary = salary;
    }
}
5.2. 创建存储库接口

由于我们在项目中使用了spring data JPA starter,我们可以创建一个存储库接口并扩展JpaRepository接口,并提供这个存储库需要管理的实体,在本例中是Employee以及主键的类型。

package com.javadevjournal.springbooth2.repository;

import com.javadevjournal.springbooth2.model.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface EmployeeRepository extends JpaRepository < Employee, Integer > {
    
}
5.3. 创建服务

然后我们将创建我们的服务类,它将包含对雇员实体执行CRUD操作的逻辑。

package com.javadevjournal.springbooth2.service;

import com.javadevjournal.springbooth2.model.Employee;
import com.javadevjournal.springbooth2.repository.EmployeeRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class EmployeeService {

    @Autowired
    EmployeeRepository employeeRepository;

    public List getAllEmployees() {
        List employees = new ArrayList();
        employeeRepository.findAll().forEach(employee - > employees.add(employee));
        return employees;
    }

    public Employee getEmployeeById(int id) {
        return employeeRepository.findById(id).get();
    }

    public void saveOrUpdate(Employee employee) {
        employeeRepository.save(employee);
    }

    public void delete(int id) {
        employeeRepository.deleteById(id);
    }
}
5.4. 休息控制器

为了测试Spring Boot与H2数据库,让我们创建一个简单的REST控制器来测试我们的CURD方法。

package com.javadevjournal.springbooth2.controller;

import com.javadevjournal.springbooth2.model.Employee;
import com.javadevjournal.springbooth2.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
public class EmployeeController {

    @Autowired
    EmployeeService employeeService;

    @GetMapping("/employees")
    private List getAllEmployees() {
        return employeeService.getAllEmployees();
    }

    @GetMapping("/employees/{id}")
    private Employee getEmployeeById(@PathVariable("id") int id) {
        return employeeService.getEmployeeById(id);
    }

    @PostMapping("/employees")
    private ResponseEntity createEmployee(@RequestBody Employee employee) {
        try {
            employeeService.saveOrUpdate(employee);
        } catch (Exception exception) {
            return new ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return new ResponseEntity("New employee created with id: " + employee.getId(), HttpStatus.CREATED);
    }

    @DeleteMapping("/employees/{id}")
    private ResponseEntity deleteById(@PathVariable("id") int id) {
        try {
            employeeService.delete(id);
        } catch (Exception exception) {
            return new ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return new ResponseEntity("Employee deleted with id: " + id, HttpStatus.OK);
    }
}

6. 运行应用程序

让我们运行我们的应用程序,看看H2数据库与Spring Boot的整体配置是如何工作的。通过点击运行我们的主类来运行我们的应用程序。嵌入式Tomcat服务器将在默认端口8080启动。

我们将从浏览器上开始点击我们的终端,或者,我们也可以使用postman。


获取所有雇员


创建新的雇员


删除雇员

7. 使用Spring Boot的H2控制台

H2数据库有一个嵌入式GUI控制台,用于浏览数据库的内容和运行查询。为了启用H2控制台并与Spring Boot一起使用,我们需要在application.properties中添加以下属性: spring.h2.console.enabled=true.在浏览器中打开URL并点击连接到数据库


H2 Console With Spring Boot

连接后,我们可以看到数据库结构,包括雇员表的细节和在应用程序启动时使用data.sql脚本填充的内容。

让我们尝试使用H2控制台删除一个雇员,并使用POSTMAN的删除请求删除另一个雇员。


使用H2控制台删除一个雇员

我们可以看到,employee表被更新了,并且两行已经被删除。

总结

在这篇文章中,我们看到了如何使用Spring Boot与H2数据库。我们看到了如何创建一个Spring Boot应用程序并配置H2。我们还使用H2控制台访问数据库,并在运行时通过我们的REST APIs操作数据。本文的源代码可在我们的GitHub Repository上找到。

相关文章