Spring Boot2 系列教程(三十一)Spring Boot 构建 RESTful 风格应用

RESTful ,到如今相信已经没人不知道这个东西了吧!关于 RESTful 的概念,我这里就不作过多介绍了,传统的 Struts 对 RESTful 支持不够友好 ,可是 SpringMVC 对于 RESTful 提供了很好的支持,常见的相关注解有:html

@RestController
@GetMapping
@PutMapping
@PostMapping
@DeleteMapping
@ResponseBody
...

这些注解都是和 RESTful 相关的,在移动互联网中,RESTful 获得了很是普遍的使用。RESTful 这个概念提出来很早,可是之前没有移动互联网时,咱们作的大部分应用都是先后端不分的,在这种架构的应用中,数据基本上都是在后端渲染好返回给前端展现的,此时 RESTful 在 Web 应用中基本就没用武之地,移动互联网的兴起,让咱们一套后台对应多个前端项目,所以先后端分离,RESTful 顺利走上前台。前端

Spring Boot 继承自 Spring + SpringMVC, SpringMVC 中对于 RESTful 支持的特性在 Spring Boot 中全盘接收,同时,结合 Jpa 和 自动化配置,对于 RESTful 还提供了更多的支持,使得开发者几乎不须要写代码(不多几行),就能快速实现一个 RESTful 风格的增删改查。java

接下来,松哥经过一个简单的案例,来向你们展现 Spring Boot 对于 RESTful 的支持。mysql

实战

建立工程

首先建立一个 Spring Boot 工程,引入 WebJpaMySQLRest Repositories 依赖:git

建立完成后,还须要锁定 MySQL 驱动的版本以及加入 Druid 数据库链接池,完整依赖以下:github

<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-data-rest</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
        <version>1.1.10</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
        <version>5.1.27</version>
    </dependency>
</dependencies>

配置数据库

主要配置两个,一个是数据库,另外一个是 Jpa:web

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.url=jdbc:mysql:///test01
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.database-platform=mysql
spring.jpa.database=mysql

这里的配置,和 Jpa 中的基本一致。spring

前面五行配置了数据库的基本信息,包括数据库链接池、数据库用户名、数据库密码、数据库链接地址以及数据库驱动名称。sql

接下来的五行配置了 JPA 的基本信息,分别表示生成 SQL 的方言、打印出生成的 SQL 、每次启动项目时根据实际状况选择是否更新表、数据库平台是 MySQL。数据库

这两段配置是关于 MySQL + JPA 的配置,没用过 JPA 的小伙伴能够参考松哥以前的 JPA 文章:http://www.javaboy.org/2019/0407/springboot-jpa.html

构建实体类

@Entity(name = "t_book")
public class Book {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(name = "book_name")
    private String name;
    private String author;
    //省略 getter/setter
}
public interface BookRepository extends JpaRepository<Book,Long> {
}

这里一个是配置了一个实体类 Book,另外一个则是配置了一个 BookRepository ,项目启动成功后,框架会根据 Book 类的定义,在数据库中自动建立相应的表,BookRepository 接口则是继承自 JpaRepository ,JpaRepository 中自带了一些基本的增删改查方法。

好了,代码写完了。

啥?你好像啥都没写啊?是的,啥都没写,啥都不用写,一个 RESTful 风格的增删改查应用就有了,这就是 Spring Boot 的魅力!

测试

此时,咱们就能够启动项目进行测试了,使用 POSTMAN 来测试(你们也能够自行选择趁手的 HTTP 请求工具)。

此时咱们的项目已经默认具有了一些接口,咱们分别来看:

根据 id 查询接口

这个接口表示根据 id 查询某一本书:

分页查询

这是一个批量查询接口,默认请求路径是类名首字母小写,而且再加一个 s 后缀。这个接口其实是一个分页查询接口,没有传参数,表示查询第一页,每页 20 条数据。

查询结果中,除了该有的数据以外,也包含了分页数据:

分页数据中:

  1. size 表示每页查询记录数
  2. totalElements 表示总记录数
  3. totalPages 表示总页数
  4. number 表示当前页数,从0开始计

若是要分页或者排序查询,可使用 _links 中的连接。http://127.0.0.1:8080/books?page=1&size=3&sort=id,desc

添加

也能够添加数据,添加是 POST 请求,数据经过 JSON 的形式传递,以下:

添加成功以后,默认会返回添加成功的数据。

修改

修改接口默认也是存在的,数据修改请求是一个 PUT 请求,修改的参数也是经过 JSON 的形式传递:

默认状况下,修改为功后,会返回修改为功的数据。

删除

固然也能够经过 DELETE 请求根据 id 删除数据:

删除成功后,是没有返回值的。

不须要几行代码,一个基本的增删改查就有了。

这些都是默认的配置,这些默认的配置实际上都是在 JpaRepository 的基础上实现的,实际项目中,咱们还能够对这些功能进行定制。

查询定制

最普遍的定制,就是查询,由于增删改操做的变化不像查询这么丰富。对于查询的定制,很是容易,只须要提供相关的方法便可。例如根据做者查询书籍:

public interface BookRepository extends JpaRepository<Book,Long> {
    List<Book> findBookByAuthorContaining(@Param("author") String author);
}

注意,方法的定义,参数要有 @Param 注解。

定制完成后,重启项目,此时就多了一个查询接口,开发者能够经过 http://localhost:8080/books/search 来查看和 book 相关的自定义接口都有哪些:

查询结果表示,只有一个自定义接口,接口名就是方法名,并且查询结果还给出了接口调用的示例。咱们来尝试调用一下本身定义的查询接口:

开发者能够根据实际状况,在 BookRepository 中定义任意多个查询方法,查询方法的定义规则和 Jpa 中如出一辙(不懂 Jpa 的小伙伴,能够参考干货|一文读懂 Spring Data Jpa!,或者在松哥我的网站 www.javaboy.org 上搜索 JPA,有相关教程参考)。可是,这样有一个缺陷,就是 Jpa 中方法名太长,所以,若是不想使用方法名做为接口名,则能够自定义接口名:

public interface BookRepository extends JpaRepository<Book, Long> {
    @RestResource(rel = "byauthor",path = "byauthor")
    List<Book> findBookByAuthorContaining(@Param("author") String author);
}

@RestResource 注解中,两个参数的含义:

  • rel 表示接口查询中,这个方法的 key
  • path 表示请求路径

这样定义完成后,表示接口名为 byauthor ,重启项目,继续查询接口:

除了 relpath 两个属性以外,@RestResource 中还有一个属性,exported 表示是否暴露接口,默认为 true ,表示暴露接口,即方法能够在前端调用,若是仅仅只是想定义一个方法,不须要在前端调用这个方法,能够设置 exported 属性为 false

若是不想暴露官方定义好的方法,例如根据 id 删除数据,只须要在自定义接口中重写该方法,而后在该方法上加 @RestResource 注解而且配置相关属性便可。

public interface BookRepository extends JpaRepository<Book, Long> {
    @RestResource(rel = "byauthor",path = "byauthor")
    List<Book> findBookByAuthorContaining(@Param("author") String author);
    @Override
    @RestResource(exported = false)
    void deleteById(Long aLong);
}

另外生成的 JSON 字符串中的集合名和单个 item 的名字都是能够自定义的:

@RepositoryRestResource(collectionResourceRel = "bs",itemResourceRel = "b",path = "bs")
public interface BookRepository extends JpaRepository<Book, Long> {
    @RestResource(rel = "byauthor",path = "byauthor")
    List<Book> findBookByAuthorContaining(@Param("author") String author);
    @Override
    @RestResource(exported = false)
    void deleteById(Long aLong);
}

path 属性表示请求路径,请求路径默认是类名首字母小写+s,能够在这里本身从新定义。

其余配置

最后,也能够在 application.properties 中配置 REST 基本参数:

spring.data.rest.base-path=/api
spring.data.rest.sort-param-name=sort
spring.data.rest.page-param-name=page
spring.data.rest.limit-param-name=size
spring.data.rest.max-page-size=20
spring.data.rest.default-page-size=0
spring.data.rest.return-body-on-update=true
spring.data.rest.return-body-on-create=true

配置含义,从上往下,依次是:

  1. 给全部的接口添加统一的前缀
  2. 配置排序参数的 key ,默认是 sort
  3. 配置分页查询时页码的 key,默认是 page
  4. 配置分页查询时每页查询页数的 key,默认是size
  5. 配置每页最大查询记录数,默认是 20 条
  6. 分页查询时默认的页码
  7. 更新成功时是否返回更新记录
  8. 添加成功时是否返回添加记录

总结

本文主要向你们介绍了 Spring Boot 中快速实现一个 RESTful 风格的增删改查应用的方案,总体来讲仍是比较简单的,并不难。相关案例我已上传到 GitHub 上了,小伙伴能够自行下载:https://github.com/lenve/javaboy-code-samples

关于本文,有问题欢迎留言讨论。

扫码关注松哥,公众号后台回复 2TB,获取松哥独家 超2TB 免费 Java 学习干货

相关文章
相关标签/搜索