近日發現了spring-data-rest項目,於是創建這個spring-data-rest-glance來體驗一下。
本例使用springboot,並使用了 spring-data-rest 和 spring-data-jpa
此二者結合:真的可以實現10分鍾創建一個rest應用,下面開始演示spring-data-rest+spring-data-rest的魔力
本例假設你已經熟悉或者了解 springboot,spring-data-jpa
創建項目
我們先創建一個springboot項目,可以通過 start.spring.io 或者在idea里邊new module --> spring Initializer 的方式。
創建好項目之后,我們的依賴配置是這樣的:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<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>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
本例使用的是h2數據庫,所以加了h2數據庫的依賴。
我們創建一個person
表,並創建person
的entity
和repository
,讓repository
繼承JpaRepository
。
關鍵的來了:@RepositoryRestResource(collectionResourceRel = "person", path = "person")
我們給repository
加上一個@RepositoryRestResource
注解,我們來啟動項目,看看此注解的魔力。
啟動項目
訪問:htttp://localhost:8000/person
得到的結果如下:
{
"_embedded": {
"person": []
},
"_links": {
"self": {
"href": "http://localhost:8000/person{?page,size,sort}",
"templated": true
},
"profile": {
"href": "http://localhost:8000/profile/person"
},
"search": {
"href": "http://localhost:8000/person/search"
}
},
"page": {
"size": 20,
"totalElements": 0,
"totalPages": 0,
"number": 0
}
}
我們看到 person
節點並無內容。同時請注意 _links 節點下的內容。我們下面將會用到它。
添加person
我們使用POST方式訪問 http://localhost:8000/person
並提交如下 JSON 數據:
{"firstName": "tomcat", "lastName": "cat"}
如此,就完成了添加操作,你可以多添加幾條數據試試。
查看person 及 person 列表
我們再次在瀏覽器中訪問(GET) http://localhost:8000/person
。得到的結果中,JSON數據和第一步中一樣,person節點中不再是空的了。
[
{
"firstName": "tomcat",
"lastName": "cat",
"_links": {
"self": {
"href": "http://localhost:8000/person/1"
},
"person": {
"href": "http://localhost:8000/person/1"
}
}
}
]
我們可以繼續多添加幾條數據,方便下面展示查詢。在添加多條信息之后,如果想查看某個person的詳情,例如:http://localhost:8000/person/7
{
"firstName": "李",
"lastName": "四",
"_links": {
"self": {
"href": "http://localhost:8000/person/7"
},
"person": {
"href": "http://localhost:8000/person/7"
}
}
}
條件查詢
假設我們需要根據用戶名查詢用戶,我們在PersonRepository
中添加一個方法findByLastName
.
托spring-data-jpa的福,我們只需要寫這樣的一行代碼,然后什么都不用做,spring-data-jpa會解析findByLastName
並應用到查詢上。
List<Person> findByLastName(@Param("name") String name);
寫好上面的代碼之后,我們重啟項目,訪問http://localhost:8000/person/search
結果如下:
{
"_links": {
"findByLastName": {
"href": "http://localhost:8000/person/search/findByLastName{?name}",
"templated": true
},
"findByFirstName": {
"href": "http://localhost:8000/person/search/findByFirstName{?name}",
"templated": true
},
"self": {
"href": "http://localhost:8000/person/search"
}
}
}
我們可以看到,這里已經列出了當前可用的search方法。我們訪問:http://localhost:8000/person/search/findByLastName?name=cat
{
"person": [
{
"firstName": "tomcat",
"lastName": "cat",
"_links": {
"self": {
"href": "http://localhost:8000/person/1"
},
"person": {
"href": "http://localhost:8000/person/1"
}
}
},
{
"firstName": "tom",
"lastName": "cat",
"_links": {
"self": {
"href": "http://localhost:8000/person/2"
},
"person": {
"href": "http://localhost:8000/person/2"
}
}
}
]
}
我們可以看到,這里通過findByLastName?name=cat
找到了兩個人:tomcat cat 和 tom cat
分頁查詢
為了演示分頁,我們先多添加幾條用戶數據。在第一步中展示的結果中,我們可以看到這樣的一行數據:
http://localhost:8000/person{?page,size,sort}
這提示了我們分頁的使用方法,我們來訪問http://localhost:8000/person?page=2&size=3
試試,即:訪問第2頁數據,頁大小是3。
下面貼出 關鍵結果的節點:
{
"_embedded": {
"person": [
{
"firstName": "李",
"lastName": "四",
"_links": {
"self": {
"href": "http://localhost:8000/person/7"
},
"person": {
"href": "http://localhost:8000/person/7"
}
}
},
{
"firstName": "王",
"lastName": "五",
"_links": {
"self": {
"href": "http://localhost:8000/person/8"
},
"person": {
"href": "http://localhost:8000/person/8"
}
}
}
]
},
"page": {
"size": 3,
"totalElements": 8,
"totalPages": 3,
"number": 2
}
}
確實查到了數據,結果對不對呢?根據上面的從上面的結果看出,我們添加8條數據,頁大小是3,所以:
總頁數 = 3 第一頁 3條數據 第二頁 3條數據 第三頁 2條數據
我們訪問的是,http://localhost:8000/person?page=2&size=3
page=2,但是實際上取的是2條數據——是第3頁。那么頁碼其實是從0開始的對嗎?
我們繼續訪問 http://localhost:8000/person?page=0&size=3
http://localhost:8000/person?page=1&size=3
可以發現,確實是如此,頁碼從0開始。any way
controller 去哪里了
到目前為止,我們只寫了很少的代碼,只寫了DAO,但是卻已經實現了增刪改查resp api。我們甚至連 controller都沒有寫,就訪問了這么多的rest url。
我們只通過@RepositoryRestResource(collectionResourceRel = "person", path = "person")
在 dao 中就能夠把 /path路徑暴露出來。
邊一切都有了,這就是spring-data-rest的魔力。
自定義 spring-data-rest 魔力之外的controller可以嗎
當然可以了,上面我們所訪問的 /person/* 的地址,是從dao中通過 @RepositoryRestResource
注解暴露出去的。
那么現在我們就手寫一個controller,訪問路徑也叫/person,即:@RequestMapping("/person")
@Controller
@RequestMapping("/person")
public class PersonController {
@RequestMapping("/hello")
@ResponseBody
public String hello(){
return " Hello,welcome to the normal controller! ";
}
}
我們自己創建的controller訪問路徑也是,/person
還創建了一個自定義的 hello
方法,這個/person
和dao里邊暴露的/person
能共存,並和諧相處嗎?我們訪問看看:http://localhost:8000/person/hello
我們在瀏覽器中可以看到:
Hello,welcome to the normal controller!
很完美,這里我們可以得出,我們能利用spring-data-rest + spring-data-jpa實現基本的增刪改查api.
我們只需要自己去寫復雜的api就行了,簡單的根本不用寫,豈不是很快!
總結
至此,我們體驗了一下 spring-data-rest。總有“刁民”說java開發很慢,代碼太多了。多嗎?不多啊,我們這里使用spring-data-jpa
加上spring-data-rest,只寫了很少的代碼就實現了大部分基礎的功能了。下次開發新項目,可以嘗試使用 spring-data-rest加spring-data-jpa了。
推薦閱讀
探索Java9 模塊系統和反應流
Java8系列- 如何用Java8 Stream API找到心儀的女朋友
Java8系列- 何用Java8 Stream API進行數據抽取與收集
Spring Security 入門原理及實戰
SpringMVC是怎么工作的,SpringMVC的工作原理
Mybatis Mapper接口是如何找到實現類的-源碼分析
小程序雲開發:菜鳥也能全棧做產品
CORS詳解,CORS原理分析
工作6年,失業19天