Spring Boot教程 | 第四篇:使用Spring Data REST快速实现RESTful风格接口及更新时Null问题

一、简介

Spring Boot完整教程 | 主页及目录

上一篇中,我们“手动”实现了RESTful风格的接口,我们可以使用Spring Data REST自动帮我们生成这一系列的接口。Spring Data REST可以将Repository自动输出为REST资源。目前Spring Data REST支持将Spring Data JPA、Spring Data MongoDB、Spring Data Neo4j、Spring Data Gemfire以及Spring Data Cassandra的Repository自动转换成REST服务。

 

二、项目实现

引入spring-boot-starter-data-rest依赖

        
            org.springframework.boot
            spring-boot-starter-data-rest
        

 在Dao接口StudentDao增加@RepositoryRestResource注解,其中path即为地址映射

package com.kcsm.training.bootdemo.dao;

        import com.kcsm.training.bootdemo.entity.Student;
        import org.springframework.data.jpa.repository.JpaRepository;
        import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
        import org.springframework.data.rest.core.annotation.RepositoryRestResource;

/**
 * 学生信息数据库访问接口
 *
 * @author lqk
 * @date 2019/7/9 15:43
 */
@RepositoryRestResource(path = "student")
public interface StudentDao  extends JpaRepository, JpaSpecificationExecutor {

}

 

2.1 查询

重启项目后发送GET请求:http://localhost:8080/student,可返回数据库表中数据

Spring Boot教程 | 第四篇:使用Spring Data REST快速实现RESTful风格接口及更新时Null问题_第1张图片

 

2.2 新增

发送POST请求:http://localhost:8080/student,发送时请求体带入新建对象参数,类型为application/json,参数为

Spring Boot教程 | 第四篇:使用Spring Data REST快速实现RESTful风格接口及更新时Null问题_第2张图片

{
	"name":"data rest",
	"age":1
}

执行后,新增数据成功

Spring Boot教程 | 第四篇:使用Spring Data REST快速实现RESTful风格接口及更新时Null问题_第3张图片

 

2.3 删除

发送DELETE请求,执行删除操作。此时数据库数据为

Spring Boot教程 | 第四篇:使用Spring Data REST快速实现RESTful风格接口及更新时Null问题_第4张图片

发送DELETE请求,请求路径带入第三条数据主键,删除第三条数据。执行后删除成功

Spring Boot教程 | 第四篇:使用Spring Data REST快速实现RESTful风格接口及更新时Null问题_第5张图片

2.4 更新

1、POST请求中,http://localhost:8080/student/,请求体带主键信息,即为更新

Spring Boot教程 | 第四篇:使用Spring Data REST快速实现RESTful风格接口及更新时Null问题_第6张图片

2、PUT请求中,请求地址带主键信息,请求体为更新更新内容,即可更新。

更新此条数据,http://localhost:8080/student/402881b66bda7c5d016bda9373450001

{
	"name":"更新1",
	"age":2
}

执行后:

Spring Boot教程 | 第四篇:使用Spring Data REST快速实现RESTful风格接口及更新时Null问题_第7张图片

 

三、自定义查询方法

上一篇中我们定义了根据性别查询学生信息的方法,使用Data RSET,我们可以直接访问这一方法,而不需要再写service和controller。此时StudentDao代码如下

package com.kcsm.training.bootdemo.dao;

import com.kcsm.training.bootdemo.entity.Student;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;

import java.util.List;

/**
 * 学生信息数据库访问接口
 *
 * @author lqk
 * @date 2019/7/9 15:43
 */
@RepositoryRestResource(path = "student")
public interface StudentDao  extends JpaRepository, JpaSpecificationExecutor {

    /**
     * 根据性别查询学生信息
     *
     * @author lqk
     * @param  gender [String]性别
     * @return java.util.List
     * @date   2019/7/10 9:16
     */
    public List findAllByGender(String gender);

}

通过/search,我们可以看到自定义的方法http://localhost:8080/student/search

Spring Boot教程 | 第四篇:使用Spring Data REST快速实现RESTful风格接口及更新时Null问题_第8张图片

通过/search/方法名,即可以访问此方法http://localhost:8080/student/search/findAllByGender?gender=male

Spring Boot教程 | 第四篇:使用Spring Data REST快速实现RESTful风格接口及更新时Null问题_第9张图片

 

四、更新时注意事项

细心的同学可能以及发现,当我使用POST或者PUT更新数据时,当消息体字段不全时,此条数据的此字段会变为null。例如,现在表中的数据为:

Spring Boot教程 | 第四篇:使用Spring Data REST快速实现RESTful风格接口及更新时Null问题_第10张图片

更新此条数据,消息体中只放入改变了的name的值,执行更新

Spring Boot教程 | 第四篇:使用Spring Data REST快速实现RESTful风格接口及更新时Null问题_第11张图片

此时我们发现gender与age的值全部为null了

Spring Boot教程 | 第四篇:使用Spring Data REST快速实现RESTful风格接口及更新时Null问题_第12张图片

我们项目封了 Data REST,又封了 Data JPA,其实最后执行持久化到数据库里,是基于Hibernate的。当我们的json或者其他格式的数据转换成这个需要持久化的对象时,没有的属性转换时自然就为空值,保存到数据库里的也就为空值。 所以做更新时,后台给前台对象的哪些属性,调用RESTful更新接口时,前台也要给后台返回全部字段,这样不管如何增减字段,都由后台控制,前端只需返回原样的数据模型即可。后端人员在编写接口说明时,一定要特别注意这个细节,否则处理不当可能会发生生产事故。

还有另外一种方法就是后台接收到更新请求后,通过主键反查出此对象(findById),通过反射直接赋值。此种方式需重写更新方法不说,还牺牲了后台的效率,并不推荐。

 

五、总结

通过以上的演示,无论是基本方法还是自定义方法,Spring Data REST都可快速帮我们实现了HAL数据风格的RESTful API接口。HAL概念请参考:分布式架构设计之Rest API HAL。换句话来说,Spring Data REST帮我们写了service层和controller层的代码。

 

你可能感兴趣的:(Spring,Boot)