跳转至

Spring Boot H2 REST 教程

原文: http://zetcode.com/articles/springbootresth2/

在本教程中,我们将使用 H2 数据库创建一个简单的 Spring Boot RESTful 应用。

Spring 是用于创建企业应用的流行 Java 应用框架。 Spring Boot 是一种以最少的精力创建独立的,基于生产级别的基于 Spring 的应用的方法。

Apache Tomcat 是由 Apache 软件基金会(ASF)开发的开源 Java Servlet 容器。 Tomcat 实现了几种 Java EE 规范,包括 Java Servlet,JavaServer Pages(JSP),Java EL 和 WebSocket。 Tomcat 可以独立和嵌入式模式运行。

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

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

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

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

应用

我们的应用是一个运行在嵌入式 Tomcat 服务器上的 Spring Boot RESTful 应用。 它以 JSON 格式从 H2 数据库返回数据。 该应用使用JdbcTemplate简化 JDBC 编程。

$ tree
.
├── pom.xml
└── src
    ├── main
    │   ├── java
    │   │   └── com
    │   │       └── zetcode
    │   │           ├── Application.java
    │   │           ├── bean
    │   │           │   └── City.java
    │   │           ├── controller
    │   │           │   └── MyController.java
    │   │           └── service
    │   │               ├── CityService.java
    │   │               └── ICityService.java
    │   └── resources
    │       ├── application.yml
    │       ├── data-h2.sql
    │       └── schema-h2.sql
    └── test
        └── java         

这是项目结构。

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

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.zetcode</groupId>
    <artifactId>SpringBootRestH2</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.3.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-devtools</artifactId>
            <optional>true</optional>
        </dependency>     

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

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

    </dependencies>       

</project>

这是 Maven 构建文件。 h2依赖项是 H2 数据库的驱动程序。 spring-boot-devtools启用热插拔,禁用模板缓存并启用实时重载。 spring-boot-starter-web是使用 Spring MVC 构建 Web(包括 RESTful)应用的入门程序。 spring-boot-starter-jdbc是在 Spring Boot 中使用 JDBC 的入门工具。

application.yml

server:
    port: 8086
    context-path: /rest

spring: 
    main:
        banner-mode: "off"       
    datasource:
        platform: h2
        driverClassName: org.h2.Driver
        url: jdbc:h2:mem:test;MODE=PostgreSQL

logging: 
    level: 
        org: 
            springframework: ERROR

application.yml文件包含 Spring Boot 应用的各种配置设置。 我们具有服务器端口和上下文路径(应用名称)的映射。 使用banner-mode属性,我们可以关闭 Spring 横幅。 该平台值用在 SQL 初始化脚本中:schema-${platform}.sqldata-${platform}.sql。 我们将 H2 设置为使用 PostgreSQL 兼容模式。 H2 数据库在内存中运行。 另外,我们将 spring 框架的日志记录级别设置为ERROR。 该文件位于src/main/resources目录中。

City.java

package com.zetcode.bean;

public class City {

    private Long id;
    private String name;
    private int population;

    public City() {
    }

    public City(Long id, String name, int population) {
        this.id = id;
        this.name = name;
        this.population = population;
    }

    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 getPopulation() {
        return population;
    }

    public void setPopulation(int population) {
        this.population = population;
    }

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

这是City bean。

schema-h2.sql

CREATE TABLE CITIES(ID BIGINT PRIMARY KEY AUTO_INCREMENT, 
                  NAME VARCHAR(30), POPULATION BIGINT);

该 SQL 脚本创建CITIES表。

data-h2.sql

INSERT INTO CITIES(NAME, POPULATION) VALUES('Bratislava', 432000);
INSERT INTO CITIES(NAME, POPULATION) VALUES('Budapest', 1759000);
INSERT INTO CITIES(NAME, POPULATION) VALUES('Prague', 1280000);
INSERT INTO CITIES(NAME, POPULATION) VALUES('Warsaw', 1748000);
INSERT INTO CITIES(NAME, POPULATION) VALUES('Los Angeles', 3971000);
INSERT INTO CITIES(NAME, POPULATION) VALUES('New York', 8550000);
INSERT INTO CITIES(NAME, POPULATION) VALUES('Edinburgh', 464000);
INSERT INTO CITIES(NAME, POPULATION) VALUES('Berlin', 3671000);

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

ICityService.java

package com.zetcode.service;

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

public interface ICityService {

    public List<City> findAll();
    public City findById(Long id);
}

ICityService提供了获取所有城市并通过其 ID 从数据源获取城市的契约方法。

CityService.java

package com.zetcode.service;

import com.zetcode.bean.City;
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 CityService implements ICityService {

    @Autowired
    private JdbcTemplate jtm;

    @Override
    public List<City> findAll() {

        String sql = "SELECT * FROM CITIES";

        List<City> cities = jtm.query(sql, new BeanPropertyRowMapper(City.class));

        return cities;
    }

    @Override
    public City findById(Long id) {

        String sql = "SELECT * FROM CITIES WHERE ID=?";

        City city = (City) jtm.queryForObject(sql, new Object[]{id},
                new BeanPropertyRowMapper(City.class));

        return city;
    }
}

CityService包含findAll()findById()方法的实现。 我们使用 Spring 的JdbcTemplate来执行 SQL 代码。

@Autowired
private JdbcTemplate jtm;

注入JdbcTemplate

String sql = "SELECT * FROM CITIES";

这是从CITIES表中选择所有城市的 SQL。

List<City> cities = jtm.query(sql, new BeanPropertyRowMapper(City.class));

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

String sql = "SELECT * FROM CITIES WHERE ID=?";

这是用于从CITIES表中选择由 ID 标识的特定城市的 SQL。

City city = (City) jtm.queryForObject(sql, new Object[]{id},
        new BeanPropertyRowMapper(City.class));

要从CITIES表中获得一行,我们使用queryForObject()方法。

MyController.java

package com.zetcode.controller;

import com.zetcode.bean.City;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import com.zetcode.service.ICityService;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {

    @Autowired
    private ICityService cityService;

    @RequestMapping("/cities")
    public List<City> findCities() {

        return cityService.findAll();
    }

    @RequestMapping("/cities/{userId}")
    public City findCity(@PathVariable Long userId) {

        return cityService.findById(userId);
    }
}

这是 Spring Boot RESTful 应用的控制器类。 @RestController注解创建一个 RESTful 控制器。 传统的 MVC 控制器使用ModelAndView,而 RESTful 控制器仅返回对象,并且对象数据以 JSON 或 XML 格式直接写入 HTTP 响应。

@Autowired
private ICityService cityService;

我们在countryService字段中插入ICityService

@RequestMapping("/cities")
public List<City> findCities() {

    return cityService.findAll();
}

@RequestMapping注解用于将 Web 请求映射到 Spring 控制器方法。 在这里,我们将具有/cities路径的请求映射到控制器的findCities()方法。 默认请求是 GET 请求。

我们不需要手动将City域对象转换为 JSON。 因为 Jackson 2 在类路径中((通过spring-boot-starter-web包含在内),所以 Spring 会自动选择MappingJackson2HttpMessageConverterCity实例转换为 JSON。

Application.java

package com.zetcode;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

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

Application设置 Spring Boot 应用。 @SpringBootApplication启用自动配置和组件扫描。

$ mvn spring-boot:run

使用mvn spring-boot:run命令,运行应用。 该应用部署在嵌入式 Tomcat 服务器上。

$ curl localhost:8086/rest/cities
[{"id":1,"name":"Bratislava","population":432000},{"id":2,"name":"Budapest","population":1759000},
{"id":3,"name":"Prague","population":1280000},{"id":4,"name":"Warsaw","population":1748000},
{"id":5,"name":"Los Angeles","population":3971000},{"id":6,"name":"New York","population":8550000},
{"id":7,"name":"Edinburgh","population":464000},{"id":8,"name":"Berlin","population":3671000}]

使用curl命令,我们可以获得所有城市。

$ curl localhost:8086/rest/cities/1
{"id":1,"name":"Bratislava","population":432000}

在这里,我们得到了一个由其 ID 标识的城市。

在本教程中,我们创建了一个 Spring Boot RESTful 应用,该应用以 JSON 格式从 H2 数据库返回数据。 您可能也对相关教程感兴趣: Spring Boot Thymeleaf 教程Spring Boot Mustache 教程Spring Boot Swing 集成教程Spring 传统的 Spring 应用简介中的 Web 应用, Spring Boot RESTFul 应用JdbcTemplate



回到顶部