一直认为,Spring Data是与第三方组件进行数据交换的全家桶的整合,比如Spring Data Jpa是数据库使用,Spring Data LDAP是LDAP的使用,Spring Data Redis是Redis的使用,Spring Data Elasticsearch是Elasticsearch的使用。
然而,不起眼的地方有一个Spring Data Rest,按照常规定义,它是与Rest组件的数据交互?
非也,Spring Data Rest只是一种快速提供rest服务的方式,通过与Spring Data xxx整合,快速实现CRUD,自动将repository 自动输出为REST资源,目前支持Spring Data JPA、Spring Data MongoDB、Spring Data Neo4j、Spring Data GemFire、Spring Data Cassandra的 repository 自动转换成REST服务。
Spring Data REST把我们需要编写的大量REST模版接口做了自动化实现。
所以,五分钟实现rest服务不是梦,比我写文章都快!
本文以Spring Data JPA结合Spring Data Rest为例,描述如何使用Spring Data Rest。
引入spring-boot-starter-data-rest和spring-boot-starter-data-jpa,使用Spring Data JPA,就必须引入mysql-connector-java和数据源。
<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.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
配置文件中只需要配置数据源和jpa相关信息即可,如:
server.port=8040
spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/boot?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
spring.datasource.username=cff
spring.datasource.password=123456
spring.datasource.type=org.apache.commons.dbcp2.BasicDataSource
spring.datasource.dbcp2.max-wait-millis=60000
spring.datasource.dbcp2.min-idle=20
spring.datasource.dbcp2.initial-size=2
spring.datasource.dbcp2.validation-query=SELECT 1
spring.datasource.dbcp2.connection-properties=characterEncoding=utf8
spring.datasource.dbcp2.validation-query=SELECT 1
spring.datasource.dbcp2.test-while-idle=true
spring.datasource.dbcp2.test-on-borrow=true
spring.datasource.dbcp2.test-on-return=false
spring.jpa.database=MySQL
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=none
spring.jpa.hibernate.naming.implicit-strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
spring.jpa.hibernate.naming.physical-strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
需要在实体上加上Spring data jpa 需要的注解:
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import com.fasterxml.jackson.annotation.JsonIgnore;
@Entity
@Table(name = "user_info")
public class UserInfo {
@Id
@Column(name = "user_name")
private String userName;
@JsonIgnore
private String passwd;
private String name;
private String mobile;
private String valid;
@Column(name = "user_type")
private String userType;
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserName() {
return userName;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
public String getPasswd() {
return passwd;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getMobile() {
return mobile;
}
public void setValid(String valid) {
this.valid = valid;
}
public String getValid() {
return valid;
}
public void setUserType(String userType) {
this.userType = userType;
}
public String getUserType() {
return userType;
}
}
对于不想暴漏的字段,使用@JsonIgnore即可。
同时,在自定义的Repository中加入@RepositoryRestResource注解:
import java.util.List;
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 com.cff.springbootwork.domain.UserInfo;
/**
* collectionResourceRel是json的最外层显示名称,path是访问路径
*
* @author fufei
*
*/
@RepositoryRestResource(collectionResourceRel = "user", path = "user")
public interface UserInfoDao extends JpaRepository<UserInfo, String> {
List<UserInfo> findByName(@Param("name") String name);
/**
* 不暴漏删除接口
*/
@Override
@RestResource(exported = false)
void deleteById(String id);
@Override
@RestResource(exported = false)
void delete(UserInfo entity);
}
对于不需要暴漏的接口,可以使用@RestResource(exported = false)隐藏该接口。
Spring Data Rest并不妨碍你传统的写法,你仍可以定义自己的controller、service和dao等!
Springboot启动项目以后,我们就可以直接使用rest服务了。
查询所有用户,使用get请求发送http://127.0.0.1:8040/user
:
{
"_embedded" : {
"user" : [ {
"name" : null,
"mobile" : "4444",
"valid" : "0",
"userType" : "1",
"_links" : {
"self" : {
"href" : "http://127.0.0.1:8040/user/15607110725"
},
"userInfo" : {
"href" : "http://127.0.0.1:8040/user/15607110725"
}
}
}, {
"name" : null,
"mobile" : "3242",
"valid" : null,
"userType" : "2",
"_links" : {
"self" : {
"href" : "http://127.0.0.1:8040/user/3453sdf"
},
"userInfo" : {
"href" : "http://127.0.0.1:8040/user/3453sdf"
}
}
} ]
},
"_links" : {
"self" : {
"href" : "http://127.0.0.1:8040/user{?page,size,sort}",
"templated" : true
},
"profile" : {
"href" : "http://127.0.0.1:8040/profile/user"
},
"search" : {
"href" : "http://127.0.0.1:8040/user/search"
}
},
"page" : {
"size" : 20,
"totalElements" : 2,
"totalPages" : 1,
"number" : 0
}
}
上面 _links 节点下的内容提示我们
http://127.0.0.1:8040/user{?page,size,sort}
进行分页查询。http://127.0.0.1:8040/profile/user
查看user实体相关。http://127.0.0.1:8040/user/search
进行search查询(自定义的查询接口);输入http://127.0.0.1:8040/user/15607110725,就能查出15607110725这条记录:
{
"name" : "cff",
"mobile" : "4444",
"valid" : "0",
"userType" : "1",
"_links" : {
"self" : {
"href" : "http://127.0.0.1:8040/user/15607110725"
},
"userInfo" : {
"href" : "http://127.0.0.1:8040/user/15607110725"
}
}
}
输入http://127.0.0.1:8040/user?page=0&size=10&sort=mobile,desc,可以进行分页排序查询,这里的排序字段sort是根据mobile字段desc排序的:
{
"_embedded" : {
"user" : [ {
"name" : "cff",
"mobile" : "4444",
"valid" : "0",
"userType" : "1",
"_links" : {
"self" : {
"href" : "http://127.0.0.1:8040/user/15607110725"
},
"userInfo" : {
"href" : "http://127.0.0.1:8040/user/15607110725"
}
}
}, {
"name" : null,
"mobile" : "3242",
"valid" : "0",
"userType" : "1",
"_links" : {
"self" : {
"href" : "http://127.0.0.1:8040/user/3453sdf"
},
"userInfo" : {
"href" : "http://127.0.0.1:8040/user/3453sdf"
}
}
} ]
},
"_links" : {
"self" : {
"href" : "http://127.0.0.1:8040/user"
},
"profile" : {
"href" : "http://127.0.0.1:8040/profile/user"
},
"search" : {
"href" : "http://127.0.0.1:8040/user/search"
}
},
"page" : {
"size" : 10,
"totalElements" : 2,
"totalPages" : 1,
"number" : 0
}
}
输入http://127.0.0.1:8040/user/search,可以显示当前可以用来search的接口列表:
{
"_links" : {
"findByName" : {
"href" : "http://127.0.0.1:8040/user/search/findByName{?name}",
"templated" : true
},
"self" : {
"href" : "http://127.0.0.1:8040/user/search"
}
}
}
表示,可以用http://127.0.0.1:8040/user/search/findByName{?name}
来进行search操作。
输入http://127.0.0.1:8040/user/search/findByName?name=cff
:
{
"_embedded" : {
"user" : [ {
"name" : "cff",
"mobile" : "4444",
"valid" : "0",
"userType" : "1",
"_links" : {
"self" : {
"href" : "http://127.0.0.1:8040/user/15607110725"
},
"userInfo" : {
"href" : "http://127.0.0.1:8040/user/15607110725"
}
}
} ]
},
"_links" : {
"self" : {
"href" : "http://127.0.0.1:8040/user/search/findByName?name=cff"
}
}
}
使用POST方式访问 http://localhost:8040/user
并提交如下的JSON 数据:
{
"userName":"test",
"passwd":"123123",
"mobile":"21312312",
"name":"heihei"
}
这里,因为上面实体userInfo的passwd字段加了@JsonIgnore注解,提交的json中,passwd是无效的。
官方文档中说可以把@RestResource(exported = false)加到字段上,经试验无效,所以遇到这种情况还是手写controller吧。
跟保存方式一样,已经存在的字段,如果这次不填,就被更新为null了。
使用DELETE方式请求 http://localhost:8040/user/test
:
会提示405 Method Not Allowed
,这是因为我们在delete方法上加了@RestResource(exported = false)注解,去掉该注解即可,注意是delete方法,deleteById方法加不加都无所谓。
重新请求,成功删除。
Spring Data Rest 官网 很详细的说明了如何使用Spring Data Rest,尽管Spring Data Rest有很大的局限性,但5分钟搞定一个Rest服务真的很赞,而且不影响传统写法,很适合快速开发。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有