7.2 JPA 实现 REST
在Spring Boot 中,使用Spring Data JPA 和Spring Data Rest 可以快速开发出一个RESTful 应用。
自动将repository转换为rest资源,可不提供controller层接口直接访问数据。
依赖
<dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-data-jpa</artifactid> </dependency> <dependeηcy> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-data-rest</artifactid> </dependency>
在application.properties 中配置基本的数据库连接信息
创建实体类
@Entity(name = "t_book") public class Book { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; private String name; private String author; // 省略getter/setter }
创建BookRepository
public interface BookRepository extends JpaRepository<Book, Integer> { }
创建BookRepository 类继承JpaRepository, JpaRepository 中默认提供了一些基本基本的增删改查、分页查询方法。
经过如上几步,一个RESTful服务就构建成功了。
RESTful 服务构建成功后,默认的请求路径是实体类名小写再加上后缀。http: //localhost: 8080/books
添加测试
查询测试,查询是GET 请求,分页查询请求路径为/books, 分页查询请求默认每页记录数是20 条, 页数为0 (页码从0 开始计)
如果开发者想要修改请求页码和每页记录数,只需要在请求地址中携带上相关参数即可,如下请求表示查询第2 页数据并且每页记录数为3: http://localhost:8080/books?page=1&size=3
如想查询第2 页数据,每页记录数为3 ,并且按照id 倒序排列,请求地址如下:
http://localhost:8080/books?page=1&size=3&sort=id,desc
如果按照id 查询,只需要在/books 后面追加上id 即可
修改测试, 发送PUT 请求可实现对数据的修改, 对数据的修改是通过id 进行的,因此请求路径中要有id
删除测试, 发送DELETE 请求可以实现对数据的删除操作。http: //localhost:8080/books/1
DELETE 请求没有返回值,上面这个请求发送成功后, id 为1 的记录就被删除了。
自定义请求路径
默认情况下,请求路径都是实体类名小写加s,如果开发者想对请求路径进行重定义,通过@RepositoryRestResource 注解即可实现
@RepositoryRestResource(path = "bs", collectionResourceRel = "bs", itemResourceRel = "b") public interface BookRepository extends JpaRepository<Book, Integer> { }
- path 属性表示将所有请求路径中的books 都修改为bs -> http://localhost:8080/bs
- collectionResourceRel 属性表示将返回的JSON 集合中book 集合的key 修改为bs
- itemResourceRel 表示将返回的JSON 集合中的单个book 的key 修改为b
collectionResourceRel和itemResourceRel的默认值为books和book
自定义查询方法
默认的查询方法支持分页查询、排序查询以及按照id 查询,如果开发者想要按照某个属性查询,只需在BookRepository 中定义相关方法并暴露出去即可。
@RepositoryRestResource (path = "bs", collectionResourceRel = "bs", itemResourceRel = "b") public interface BookRepository extends JpaRepository<Book, Integer> {
// 若不添加@RestResource,则默认路径为http://localhost:8080/bs/search/findByAuthorContains?author=鲁迅
// 注解后的查询路径为http://localhost:8080/bs/search/author?author=鲁迅
// path属性即表示最新的路径
@RestResource(path = "author", rel = "author")
List<Book> findByAuthorContains(@Param ("author") String author);
@RestResource(path = "name", rel = "name") Book findByNameEquals(@Param ("name") String name); }
用户可以直接访问http://localhost:8080/bs/search 路径查看该实体类暴露出来了哪些查询方法
如果只是单纯地不想暴露中某个方法,则在方法上配置 @RestResource 注解,并将 exported 属性设置为 false。
@RestResource(exported = false)
List<Book> findByAuthorContains(@Param ("author") String author);
不想暴露整个Repository 接口的话
@RepositoryRestResource (exported =false) public interface BookRepository extends JpaRepository<Book, Integer> { }
配置CORS
@CrossOrigin 注解可以直接写在BookRepository 上
@CrossOrigin @RepositoryRestResource(path = "bs") public interface BookReposi tory extends JpaRepository<Book, Integer> { @RestResource(path ="author", rel = "author") List<Book> findByAuthorContains(@Param("author") String author) ;
@RestResource(path = "name", rel = "name") Book findByNameEquals(@Param("name") String name); }
如果只需要某一个方法支持跨域,那么将@CrossOrigin 注解添加到某一个方法上即可。
其他配置
开发者也可以在appIi cation. properties 中配置一些常用属性
#每页默认记录数,默认值为20 spring.data.rest.default-page-size=2 #分页查询页码参数名,默认值为page spring.data.rest.page-param-name=page #分页查询记录数参数名,默认值为size spring.data.rest.limit-param-name=size #分页查询排序参数名, 默认值为sort spring.data.rest.sort-param-name=sort #base-path 表示给所有请求路径都加上前缀 spring.data.rest.base-path=/api #添加成功时是否返回添加内容 spring.data.rest.return-body-on-create=true #更新成功时是否返回更新内容 spring.data.rest.return-body-on-update=true
当然 , 这些配置也可以在 Java 代码中配置, 且代码中配置的优先级高于application.properties 配置的优先级
@Configuration public class RestConfig extends RepositoryRestConfigurerAdapter { @Override public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) { config.setDefaultPageSize(2) .setPagePararnName("page") .setLimitParamName("size") .setSortParamName("sort") .setBasePath("/api") .setReturnBodyOnCreate(true) .setReturnBodyOnUpdate(true); }
}
author