前一篇只有用到 Spring Data, 但我們很多物件都有 CRUD 的基本操作,
你就必須寫很多 CRUD Controller, CRUD Controller, CRUD Controller, CRUD Controller......
請不要再這樣浪費生命了....
現在起你連一行程式啦都不用寫....
透過 Spring Data 原本提供的功能, 再加上這個套件
compile('org.springframework.boot:spring-boot-starter-data-rest')
然後把原本的 @Repository 換成 @RepositoryRestResource
這樣我們的 Book 物件, 一行程式都不用寫
就可以透過
POST /books
PUT /books/{bookid}
GET /books/{bookid}
DELETE /books/{bookid}
就不用一直重複去寫這些 CRUD 了
但是通常你會有需求不想讓所有 API 對外開放 ex:DELETE /books/{bookid}
你可以進一步用這個註解開控制是否對外 @RestResource(exported = false)
整個改完程式就會像這樣
build.gradle
dependencies {
compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile('org.springframework.boot:spring-boot-starter-data-rest')
compile('org.springframework.boot:spring-boot-starter-web')
runtime('com.h2database:h2')
compileOnly('org.projectlombok:lombok')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
BookRepository.java
我把 CRUD 的 Override 都列出來,
delete 功能我們控制 RestResource(exported = false) 不對外開放
package com.example.book;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
import org.springframework.data.rest.core.annotation.RestResource;
@RepositoryRestResource
public interface BookRepository extends JpaRepository<Book, Integer> {
// Prevents GET /books/:id
@Override
Book findOne(Integer id);
// Prevents GET /books
@Override
Page<Book> findAll(Pageable pageable);
// Prevents POST /books and PATCH /books/:id
@Override
Book save(Book s);
// Prevents DELETE /books/:id
@Override
@RestResource(exported = false)
void delete(Book t);
}
程式啟動後可以透過
curl -X GET http://localhost:8080
來知道這服務提供多少個 API 來操作
查詢分頁
curl -X GET 'http://localhost:8080/books?page=0&size=2&sort=bookid,desc'
{
"_embedded": {
"books": [
{
"name": "天生變態:一個擁有變態大腦的天才科學家",
"author": "詹姆斯‧法隆",
"_links": {
"self": {
"href": "http://localhost:8080/books/12"
},
"book": {
"href": "http://localhost:8080/books/12"
}
}
},
{
"name": "魔法精油寶典:102種植物香氣的能量運用",
"author": "史考特‧康寧罕",
"_links": {
"self": {
"href": "http://localhost:8080/books/11"
},
"book": {
"href": "http://localhost:8080/books/11"
}
}
}
]
},
"_links": {
"first": {
"href": "http://localhost:8080/books?page=0&size=2&sort=bookid,desc"
},
"self": {
"href": "http://localhost:8080/books"
},
"next": {
"href": "http://localhost:8080/books?page=1&size=2&sort=bookid,desc"
},
"last": {
"href": "http://localhost:8080/books?page=5&size=2&sort=bookid,desc"
},
"profile": {
"href": "http://localhost:8080/profile/books"
}
},
"page": {
"size": 2,
"totalElements": 12,
"totalPages": 6,
"number": 0
}
}
取得單一資料
curl -X GET http://localhost:8080/books/12
{
"name": "天生變態:一個擁有變態大腦的天才科學家",
"author": "詹姆斯‧法隆",
"_links": {
"self": {
"href": "http://localhost:8080/books/12"
},
"book": {
"href": "http://localhost:8080/books/12"
}
}
}
然後我們試一下刪除是不是真的會被外面 RestAPI 給刪除
curl -I -X DELETE http://localhost:8080/books/12
HTTP/1.1 405
Allow: GET,HEAD,PUT,PATCH,OPTIONS
Content-Length: 0
Date: Tue, 12 Dec 2017 01:44:29 GMT
就可以很清楚看到 405 此操作已被拒絕了
你看 CRUD 都不用重複再開發, 查詢也支援分頁
是不是大大節省我們重複寫一些基本操作的時間呢?
work smart not work hard!!
多用一些新的工具節省你的精力, 把時間花在你的商業邏輯吧~~
@Override
Book findOne(Integer id);
@Override
Optional<Book> findById(Integer id);
用來避免NullPointerException
以上為學習心得,如有錯還請指教