# Spring Boot H2 教程

> 原文： [http://zetcode.com/articles/springbooth2/](http://zetcode.com/articles/springbooth2/)

在 Spring Boot H2 教程中，我们展示了如何在 Spring Boot 中使用嵌入式 H2 内存数据库。 创建一个简单的 REST 应用。

Spring 是用于开发 Java 企业应用的 Java 应用框架。 它还有助于集成各种企业组件。 Spring Boot 使创建具有 Spring 动力的生产级应用和服务变得很容易，而对安装的要求却最低。

Jetty 是一个开源项目，提供 HTTP 服务器，HTTP 客户端和 Java Servlet 容器。 该项目是 Eclipse Foundation 的一部分。 Jetty 是一个成熟的项目，始于 1995 年。Jetty 可以轻松地嵌入到设备，工具，框架，应用服务器和群集中。

H2 是完全用 Java 创建的开源关系数据库管理系统。 它可以嵌入 Java 应用中或以客户端-服务器模式运行。 它易于部署和安装，占地面积小。

`JdbcTemplate`是一个 Spring 库，可以帮助程序员创建与关系数据库和 JDBC 一起使用的应用。 它会处理许多繁琐且容易出错的底层细节，例如处理事务，清理资源以及正确处理异常。 `JdbcTemplate`在 Spring 的`spring-jdbc`模块中提供。

JSON（JavaScript 对象表示法）是一种轻量级的数据交换格式。 人类可以轻松地进行读写，并通过机器解析并生成 JSON。 JSON 的官方互联网媒体类型为`application/json`。 JSON 文件扩展名是`.json`。

RESTFul 应用遵循 REST 体系结构样式，该样式用于设计网络应用。 RESTful 应用生成 HTTP 请求，这些请求对资源执行 CRUD（创建/读取/更新/删除）操作。

## Spring Boot RESTFul 应用

H2 可以轻松地与 Spring Boot 一起使用。 当 Spring Boot 在 POM 文件中检测到 H2 时，它会自动为该应用配置内存 H2 数据库。

以下是具有 RESTFul 服务的简单 Spring Boot 应用。 该应用与嵌入式 Jetty 服务器一起运行。

```java
$ tree
.
├── pom.xml
└── src
    ├── main
    │   ├── java
    │   │   └── com
    │   │      └── zetcode
    │   │          ├── bean
    │   │          │  └── Car.java
    │   │          ├── main
    │   │          │  └── Application.java
    │   │          ├── service
    │   │          │  ├── CarService.java
    │   │          │  └── ICarService.java
    │   │          └── web
    │   │              └── MyController.java
    │   └── resources
    │       ├── application.yml
    │       ├── data-h2.sql
    │       └── schema-h2.sql
    └── test
        └── java

```

这是项目结构。

`pom.xml`

```java
<?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 
                             http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.zetcode</groupId>
    <artifactId>SpringBootH2</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.2.RELEASE</version>
    </parent>      

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>      

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
        </dependency>        

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>      

    </dependencies>    

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>            
        </plugins>
    </build>      

</project>

```

Maven `pom.xml`文件包含 Jetty，H2 驱动程序和 Spring 框架的依赖项。

`Car.java`

```java
package com.zetcode.bean;

public class Car {

    private Long id;
    private String name;
    private int price;

    public Car() {}

    public Car(Long id, String name, int price) {
        this.id = id;
        this.name = name;
        this.price = price;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Car{" + "id=" + id + ", name=" + name + ", price=" + price + '}';
    }
}

```

这是`Car` bean 类。 它包含商品 ID，名称和价格。

`application.yml`

```java
spring: 
    datasource:
        platform: h2

```

`application.yml`是主要的 Spring Boot 配置文件。 该平台值用于 SQL 初始化脚本：`schema-${platform}.sql`和`data-${platform}.sql`中。

请注意，我们没有配置数据源。 这是因为，如果没有配置数据，Spring 会以内存模式自动配置 H2。 我们希望有一个内存数据库，因此我们让 Spring 进行自动配置。

`schema-h2.sql`

```java
CREATE TABLE Cars(ID BIGINT PRIMARY KEY AUTO_INCREMENT, 
                  NAME VARCHAR(100), PRICE INT);

```

该 SQL 脚本创建`Cars`表。

`data-h2.sql`

```java
INSERT INTO Cars(Name, Price) VALUES('Audi', 52642);
INSERT INTO Cars(Name, Price) VALUES('Mercedes', 57127);
INSERT INTO Cars(Name, Price) VALUES('Skoda', 9000);
INSERT INTO Cars(Name, Price) VALUES('Volvo', 29000);
INSERT INTO Cars(Name, Price) VALUES('Bentley', 350000);
INSERT INTO Cars(Name, Price) VALUES('Citroen', 21000);
INSERT INTO Cars(Name, Price) VALUES('Hummer', 41400);
INSERT INTO Cars(Name, Price) VALUES('Volkswagen', 21600);

```

该脚本用数据填充表。 这两个脚本都位于类路径的根目录中。

`MyController.java`

```java
package com.zetcode.web;

import com.zetcode.bean.Car;
import com.zetcode.service.ICarService;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {

    @Autowired
    private ICarService carService;

    @RequestMapping("/")
    public String index(Model model) {

        return "Home page";
    }

    @RequestMapping(name = "/cars", method = RequestMethod.GET)
    public List<Car> cars() {

        List<Car> cars = carService.findAll();

        return cars;
    }
}

```

在`MyController`中，我们有两种方法可以响应两个请求。 传统的 MVC 控制器使用视图技术执行 HTML 的服务器端渲染。 RESTful Web 服务控制器将数据写入 HTTP 响应。 默认格式为 JSON。

```java
@RestController
public class MyController {

```

`@RestController`注解在 Spring 中创建 RESTFul Web 服务。

```java
@Autowired
private ICarService carService;

```

我们将`CarService`对象注入到属性中。 服务对象用于从数据库检索数据。

```java
@RequestMapping("/")
public String index(Model model) {

    return "Home page";
}

```

对于根路径，我们返回一个字符串消息。

```java
@RequestMapping(name = "/cars", method = RequestMethod.GET)
public List<Car> cars() {

    List<Car> cars = carService.findAll();

    return cars;
}

```

在`cars()`方法中，我们使用`findAll()`方法找到所有汽车。 汽车对象列表通过 Spring 消息转换器转换为 JSON。

`ICarService.java`

```java
package com.zetcode.service;

import com.zetcode.bean.Car;
import java.util.List;

public interface ICarService {

    public List<Car> findAll();
}

```

`ICarService`提供了一种从数据源获取所有汽车的契约方法。

`CarService.java`

```java
package com.zetcode.service;

import com.zetcode.bean.Car;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

@Service
public class CarService implements ICarService {

    @Autowired
    private JdbcTemplate jtm;

    @Override
    public List<Car> findAll() {

        String sql = "SELECT * FROM Cars";

        List<Car> cars = jtm.query(sql, new BeanPropertyRowMapper(Car.class));

        return cars;
    }
}

```

`CarService`包含`findAll()`方法的实现。 我们借助`JdbcTemplate`从`Cars`表中检索所有汽车。

```java
@Autowired
private JdbcTemplate jtm;

```

注入`JdbcTemplate`。

```java
String sql = "SELECT * FROM Cars";

```

这是要执行的 SQL。 我们从`Cars`表中选择所有汽车。

```java
List<Car> cars = jtm.query(sql, new BeanPropertyRowMapper(Car.class));

```

`BeanPropertyRowMapper`将一行转换为指定映射目标类的新实例。

`Application.java`

```java
package com.zetcode.client;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication(scanBasePackages = "com.zetcode")
public class Application {

    public static void main(String[] args) {

        SpringApplication.run(Application.class, args);
    }
}

```

`Application`设置 Spring Boot 应用。

```java
$ mvn spring-boot:run

```

我们启动 Spring Boot 应用。

```java
$ curl localhost:8080
Home page

```

当我们请求主页时，我们会收到字符串消息。

```java
$ curl localhost:8080/cars
[{"id":1,"name":"Audi","price":52642},{"id":2,"name":"Mercedes","price":57127},
{"id":3,"name":"Skoda","price":9000},{"id":4,"name":"Volvo","price":29000},
{"id":5,"name":"Bentley","price":350000},{"id":6,"name":"Citroen","price":21000},
{"id":7,"name":"Hummer","price":41400},{"id":8,"name":"Volkswagen","price":21600}]

```

在这里，我们以 JSON 字符串获取汽车列表。

在本教程中，我们在 RESTFul Web 应用中使用了内存中的 H2 数据库。 该应用使用 Spring Boot 框架，并在具有嵌入式 Jetty 的 Web 环境中运行。 您可能也对这些相关教程感兴趣： [Spring Boot `DataSourceBuilder`教程](/springboot/datasourcebuilder/)， [Spring Boot iText 教程](/articles/springbootitext/)， [Spring Boot RESTFul 应用](/articles/springbootrestsimple/)， [Spring Web 应用简介](/articles/springwebfirst/)， [Spring Boot 第一个 Web 应用](/articles/springbootwebfirst/)和 [Java 教程](/lang/java/)。