Spring Data REST+JPA,打造史上最简单的RESTFul API万能接口!

1、前言

1、REST 是最近几年非常流行的的 API 设计规范,它简洁并且有层次,能基于HTTP、URL、XML以及HTML这些现有的广泛流行的协议和标准。

2、在REST中,资源是由URL来指定的,对资源的增删改查操作可以通过HTTP协议提供的GETPOSTPUTDELETE等方法来实现。

3、使用REST可以高效地利用Ehcache、Redis等主流缓存技术来提高响应速度。

4、JPA能自动创建数据表,实现与MySQL、Oracle、SQL、DB2、PgSQL等主流数据库的交互。

5、利用Spring-boot我们可以非常快速的开发一个RESTFul API接口服务。

2、项目基本框架

1、Spring-boot 2.5+

2、JDK 11+或者JDK13+

3、数据库MySQL 8.0+

4、测试软件Postman

3、创建项目并添加依赖

        <!--mysql依赖-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.23</version>
        </dependency>
        <!--jpa依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!--rest依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-rest</artifactId>
        </dependency>

4、安装MySQL8.0+

数据库我们选择开源的MySQL,并安装在本地。具体我不再详细介绍,请参考链接https://blog.csdn.net/youarenotme/article/details/109291819

我们新建一个名称为jpa的数据库,设置登录账号root的密码,不需要创建表(Jpa会自动帮我们建表)

5、在项目application.properties中对MySQL和Jpa进行相关配置

#mysql配置
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/jpa?characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=***您的MySQL root密码***
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#Jpa配置
#是否在控制台打印JPA执行过程生成的SQL
spring.jpa.show-sql=true
spring.jpa.database=mysql
#项目启动时根据实体类更新数据库中的表
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect

1、持久层是Java EE中访问数据库的核心操作,Spring-boot对常见的持久层框架都提供了自动化配置,例如JdbcTemplate、Mybatis、JPA等。

2、JdbcTemplate基础,Mybatis灵活,JPA方便。本文中我们选择Spring-boot Data JPA,可以实现自动化建表,大大减少数据库及访问代码开发量。

3、在上文对Jpa的配置中,spring.jpa.hibernate.ddl-auto的可选参数如下,我们选择update。

create启动时删数据库中的表,然后创建,退出时不删除数据表
create-drop启动时删数据库中的表,然后创建,退出时删除数据表 如果表不存在报错
update如果启动时表格式不一致则更新表,原有数据保留
validate项目启动表结构进行校验 如果不一致则报错





 

6、创建实体类Book以及接口BookRepository

1、创建实体类Book,@Entity对应MySQL数据表t_book,项目启动后系统会自动在MySQL中创建t_book表,t_book表中的字段属性会根据实体类全自动定义。

package com.example.demohelloworld.restful;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
//表明是一个实体类
@Entity(name = "t_book")
public class Book {
    //@Id表明id是主键
    @Id
    //@GeneratedValue表示主键自动生成,strategy表明生成策略
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String name;
    private String author;

    public Integer getId() { return id; }
    public void setId(Integer id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public String getAuthor() { return author; }
    public void setAuthor(String author) { this.author = author; }
}

@Id表示主键,@GeneratedValue表示主键自动生成,strategy表明生成策略,我们选择IDENTITY自增长型,strategy的相关属性如下:

TABLE 使用一个特定的数据库表格来保存主键
SEQUENCE根据底层数据库的序列来生成主键,条件是数据库支持序列
IDENTITY主键由数据库自动生成(主要是自动增长型)
AUTO主键由程序控制

2、创建接口BookRepository,继承JpaRepository,JpaRepository默认提供的一些基本的数据库操作方法,如下:

  • List<T> findAll()    查找所有
  • List<T> findAll(Sort sort)    排序查找
  • List<T> findAll(Pageable pageable)    分页查找
  • List<T> findAllById(Iterable<ID> ids)    根据ID查找
  • boolean existsById(ID id)    根据查询是否存在
  • long count()    统计数量
  • deleteById(Integer id)    根据ID删除数据
  • <S extends T> S save(S entity)    插入更新数据
  • ......
package com.example.demohelloworld.restful;
import org.springframework.data.jpa.repository.JpaRepository;
//继承JpaRepository默认提供的一些基本的数据库操作方法
public interface BookRepository extends JpaRepository<Book,Integer> {
}

7、启动项目,一个简单的RESTFul API接口就搭建完成了

1、可能有小伙伴会问“我们什么都没有写啊,接口就做完了?”,是的,这就是Spring Data REST的魅力所在,一个简单的标准的API接口就做好了。

2、启动项目,系统已经自动在MySQL中创建好了t_book表,我们添加几条数据,就可以开始测试了。

 8、使用Postman开始测试

RESTFul API默认请求路径是实体类名小写再加上s后缀,本文实体类为book,加上s后缀,即默认路径名是books。

1、查询测试,我们在Postman创建4个GET请求,注意page默认从0开始。

①查询所有数据    http://localhost:8080/books

②查询id为2的数据    http://localhost:8080/books/2

③查询第1页数据并且每页记录数为3    http://localhost:8080/books?page=0&size=3

④查询第2页数据,每页记录数为3,并且按照id倒序排列    http://localhost:8080/books?page=1&size=3&sort=id,desc

下图为③查询结果:

2、新增测试,我们在Postman创建1个POST请求,Body中放入新增的数据,选择JSON类型。

①新增数据    http://localhost:8080/books    点击Send后,服务器返回刚刚添加成功数据的基本信息以及浏览地址。

3、修改测试,我们在Postman创建1个PUT请求,对数据修改是通过id进行的,所以请求路劲中要有id,在Body中放入修改的新数据。

http://localhost:8080/books/6    我们对id为6的数据进行修改,点击Send后,服务器修改成功的最新数据和浏览地址。

4、删除测试,我们在Postman创建1个DELETE请求,对数据修改是通过id进行的,例如删除id为8的数据,请求如下。

http://localhost:8080/books/8    DELETE请求没有返回值,请求发送成功后,id为8的数据即被删除。

 9、进阶教程1:自定义请求路径、自定义查询方法

1、自定义请求路径,默认情况下,请求路径都是实体类名加小写s,本文为books,如果想重新定义,则通过@RepositoryRestResource实现。这个比较抽象,我们可以看代码。

path属性表示将所有请求路径修改为新路径,例如将books修改为bs
collectionResourceRel属性表示返回JSON集合中book集合的key修改为新名称
itemResourceRel属性表示返回JSON集合中单个book的key修改为新名称

package com.example.demohelloworld.restful;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;

@RepositoryRestResource(path = "bs",collectionResourceRel = "bs",itemResourceRel = "b")
public interface BookRepository extends JpaRepository<Book,Integer> {
}

2、自定义查询方法除去JpaRepository默认提供的一些方法,我们还可以通过注解@RestResource自定义查询方法,比如根据作者名字查询,根据书名查询等。

package com.example.demohelloworld.restful;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
import org.springframework.data.rest.core.annotation.RestResource;
import java.util.List;

@RepositoryRestResource(path = "bs",collectionResourceRel = "bs",itemResourceRel = "b")
public interface BookRepository extends JpaRepository<Book,Integer> {
    //根据作者名字来查询
    @RestResource(path = "author" ,rel="author")
    List<Book> findAllByAuthorContains(@Param("author") String author);
    //根据书名来查询
    @RestResource(path = "name" ,rel="name")
    Book findByNameEquals(@Param("name") String name);
}

1、代码中findAllByAuthorContains、findByNameEquals为Spring Data Jpa自定义JPQL。查询方法既支持JPQL也支持原生SQL,nativeQuery = true表示使用原生SQL语句

如findAllByAuthorContains等同于

    @RestResource(path = "author" ,rel="author")
    //List<Book> findAllByAuthorContains(@Param("author") String author);
    @Query(value = "select * from t_book where author like %?1%",nativeQuery = true)
    List<Book> findAllByAuthorLike(@Param("author") String author);

findByNameEquals等同于

    @RestResource(path = "name" ,rel="name")
    //Book findByNameEquals(@Param("name") String name);
    @Query(value = "select * from t_book where name =:name",nativeQuery = true)
    Book findByNameEq(@Param("name") String name);

2、创建好自定义查询,我们重启项目,打开Postman,通过http://localhost:8080/bs/search就可以查询到有哪些暴露出来的自定义方法以及路径了。

 3、通过自定义查询路径:

http://localhost:8080/bs/search/author?author=鲁迅    可以查询作者是鲁迅的书。http://localhost:8080/bs/search/name?name=西游记    可以查询书名为西游记的书。

10、进阶教程2:自定义新增修改方法,屏蔽某个方法

1、自定义新增修改方法,我们定义一个新增方法addBook和一个更新方法updateBook,这里我们采用原生SQL方式通过GET请求执行,比起查询方法,需要添加@Transactional@Modifying两个注解,分别表示回滚操作和数据表与实体缓存同步更新,这点比较重要。

package com.example.demohelloworld.restful;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
import org.springframework.data.rest.core.annotation.RestResource;
import javax.transaction.Transactional;
import java.util.List;

@RepositoryRestResource(path = "bs",collectionResourceRel = "bs",itemResourceRel = "b")
public interface BookRepository extends JpaRepository<Book,Integer> {
    //根据作者名字来查询
    @RestResource(path = "author" ,rel="author")
    List<Book> findAllByAuthorContains(@Param("author") String author);
    @RestResource(path = "name" ,rel="name")
    Book findByNameEquals(@Param("name") String name);

    //新增书Get请求
    @Transactional
    @Modifying(clearAutomatically = true)//表示数据表和实体缓存同步更新
    @Query(value = "insert into t_book(name,author) values (?1,?2)",nativeQuery = true)
    int addBook(@Param("name") String name,@Param("author") String author);//返回值为新增成功数量
    //根据id更新书Get请求
    @Transactional
    @Modifying(clearAutomatically = true)//表示数据表和实体缓存同步更新
    @Query(value = "update t_book set name=?1,author=?2 where id=?3",nativeQuery = true)
    int updateBook(@Param("name") String name,@Param("author") String author,@Param("id") Integer id);//返回值为更新成功数量
}

自定义新增和更新方法我们均通过GET请求实现。

http://localhost:8080/bs/search/addBook?name=聊斋&author=蒲松龄

表示新增书《聊斋》作者蒲松龄,返回值int addBook表示新增成功的数量,如没有返回数量则新增失败。

http://localhost:8080/bs/search/updateBook?name=西游记&author=吴承恩&id=3

表示更新id为3的书,返回值int updateBook表示更新成功数量,如没有返回值数量则更新失败。

 2、屏蔽某个方法,很多时候,API接口需要屏蔽类似删除(DELETE)等方法,这时候,我们只需要在@RepositoryRestResource或者@RestResource注解中添加exported = false即可。

@RepositoryRestResource(exported = false)表示该接口下所有的增删改查都会失效。

@RestResource(exported = false)表示某一个方法失效。

我们以屏蔽DELETE接口为例,做如下配置即可。

package com.example.demohelloworld.restful;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
import org.springframework.data.rest.core.annotation.RestResource;

@RepositoryRestResource(path = "bs",collectionResourceRel = "bs",itemResourceRel = "b")
public interface BookRepository extends JpaRepository<Book,Integer> {
    @Override
    @RestResource(exported = false)
    void deleteById(Integer id);
}

这时我们再使用Postman发起一个DELETE请求http://localhost:8080/bs/10,服务器会返回405 Method Not Allowed,表示该方法失效,已经被屏蔽。

 11、总结

1、利用Spring Data REST+JPA,可以非常快速、简单打造一个RESTFul API万能接口。

2、JPA能自动创建数据表并完成接口与几乎所有主流数据库的交互,是非常方便的。

3、JpaRepository提供丰富的增删改查方法,可以完全满足基本需要。

4、利用JPQL和原生SQL还可以非常方便的开发自定义接口。

5、RESTFul API可以和Swagger3进行集成,方便测试和减少接口文档开发量。

6、后续我还将介绍RESTFul与EHcache、Redis等缓存技术集成,打造商业级API接口,欢迎关注、留言、转发。

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
SpringSpring MVC是两个不同的框架,它们都可以用于增删查改操作。 在Spring中,可以使用Spring Data JPA来进行数据库操作。它提供了一种简单的方式来定义实体、仓库和查询方法。以下是一个简单的示例: 1.定义实体类 @Entity public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private String email; //getter和setter方法 } 2.定义仓库接口 @Repository public interface UserRepository extends JpaRepository<User, Long> { //自定义查询方法 User findByName(String name); } 3.使用仓库 @Service public class UserService { @Autowired private UserRepository userRepository; public User addUser(User user) { return userRepository.save(user); } public void deleteUser(Long userId) { userRepository.deleteById(userId); } public User updateUser(User user) { return userRepository.save(user); } public User getUserById(Long userId) { return userRepository.findById(userId).orElse(null); } public User getUserByName(String name) { return userRepository.findByName(name); } } 在Spring MVC中,可以使用Spring Data REST来创建RESTful服务。它可以自动为实体创建RESTful接口,包括增删查改操作。以下是一个简单的示例: 1.定义实体类 @Entity public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private String email; //getter和setter方法 } 2.使用Spring Data REST @RepositoryRestResource(collectionResourceRel = "users", path = "users") public interface UserRepository extends JpaRepository<User, Long> {} 3.使用HTTP请求进行操作 POST /users - 创建用户 GET /users - 获取所有用户 GET /users/{id} - 获取指定ID的用户 PUT /users/{id} - 更新指定ID的用户 DELETE /users/{id} - 删除指定ID的用户 以上是两种不同的方式来进行增删查改操作,具体使用哪种方式取决于具体的需求和场景。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值