Spring JPA Data with REST

逛 Spring 官網學習總結

個人博客:DoubleFJ の Blog


@RepositoryRestResource 看到這個註解,之前一直沒有用到過,所以想要自己試試效果,順道做下總結。

不想要看我廢話想要直接看官網的Accessing JPA Data with REST

不想要看我廢話想看大佬的Spring Boot之@RepositoryRestResource註解入門使用教程


構建項目

用 Maven 構建項目,建一個 Person 實體類,再建一個 PersonRepository 接口,這個是關鍵。

package hello;

import java.util.List;

import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;

@RepositoryRestResource(collectionResourceRel = "people", path = "people")
public interface PersonRepository extends PagingAndSortingRepository<Person, Long> {

    List<Person> findByLastName(@Param("name") String name);

}

官網是這麼介紹的:

At runtime, Spring Data REST will create an implementation of this interface automatically. Then it will use the @RepositoryRestResource annotation to direct Spring MVC to create RESTful endpoints at /people.

我們翻譯過來就是:

在運行時,Spring Data REST將自動創建此接口的實現。然後它將會在使用 @RepositoryRestResource 註解的 Spring MVC 在 /people 創建 RESTful 端點。

點進 PagingAndSortingRepository 接口看:

@NoRepositoryBean
public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> {
    Iterable<T> findAll(Sort var1);

    Page<T> findAll(Pageable var1);
}

看到該接口還是繼承了平時常使用的 CrudRepository,這就說明那些基本的增刪改查方法也都有。

爲了方便,我還寫了一個接口用來保存 Person 實體,爲後續測試使用。

@Service
public class PersonService {

    @Autowired
    PersonRepository personRepository;

    public void savePerson(Person person){
        personRepository.save(person);
    }
}
@RestController
@RequestMapping("/person")
public class PersonController {

    @Autowired
    PersonService personService;

    @PutMapping("/save")
    public String savePerson(Person person){
        personService.savePerson(person);
        return "success";
    }
}

很簡單的一個映射。

到這爲止,我們的項目就全構建好了。

嫌麻煩不想自己動手建項目的GitHub

測試功能

我這裏爲了方便,用的是 Postman 進行測試。

首先訪問 http://localhost:8080,返回的是:

{
    "_links": {
        "people": {
            "href": "http://localhost:8080/people{?page,size,sort}",
            "templated": true
        },
        "profile": {
            "href": "http://localhost:8080/profile"
        }
    }
}

再訪問 http://localhost:8080/people,返回的是:

{
    "_embedded": {
        "people": []
    },
    "_links": {
        "self": {
            "href": "http://localhost:8080/people{?page,size,sort}",
            "templated": true
        },
        "profile": {
            "href": "http://localhost:8080/profile/people"
        },
        "search": {
            "href": "http://localhost:8080/people/search"
        }
    },
    "page": {
        "size": 20,
        "totalElements": 0,
        "totalPages": 0,
        "number": 0
    }
}

因爲裏面沒有數據,我們先塞幾個數據進去,這時候就利用我們之前寫的接口來操作。如下:

我們用 PUT 方式去請求 http://localhost:8080/person/save?firstName=aaa&lastName=bbb

返回 success 就說明操作成功,成功塞入。

同樣的方式我們再多塞幾個。

塞完值之後我們接着去訪問 http://localhost:8080/people,這時候發現結果與之前的稍有不同了:

{
    "_embedded": {
        "people": [
            {
                "firstName": "aaa",
                "lastName": "bbb",
                "_links": {
                    "self": {
                        "href": "http://localhost:8080/people/1"
                    },
                    "person": {
                        "href": "http://localhost:8080/people/1"
                    }
                }
            },
            {
                "firstName": "aaa",
                "lastName": "ccc",
                "_links": {
                    "self": {
                        "href": "http://localhost:8080/people/2"
                    },
                    "person": {
                        "href": "http://localhost:8080/people/2"
                    }
                }
            },
            {
                "firstName": "jay",
                "lastName": "folger",
                "_links": {
                    "self": {
                        "href": "http://localhost:8080/people/3"
                    },
                    "person": {
                        "href": "http://localhost:8080/people/3"
                    }
                }
            }
        ]
    },
    "_links": {
        "self": {
            "href": "http://localhost:8080/people{?page,size,sort}",
            "templated": true
        },
        "profile": {
            "href": "http://localhost:8080/profile/people"
        },
        "search": {
            "href": "http://localhost:8080/people/search"
        }
    },
    "page": {
        "size": 20,
        "totalElements": 3,
        "totalPages": 1,
        "number": 0
    }
}

是的,我們剛塞的值都查出來了。

接着測試,訪問 http://localhost:8080/people/1,返回結果爲:

{
    "firstName": "aaa",
    "lastName": "bbb",
    "_links": {
        "self": {
            "href": "http://localhost:8080/people/1"
        },
        "person": {
            "href": "http://localhost:8080/people/1"
        }
    }
}

是的,就是第一條數據被查出來了,同理 /2 /3 也是。

訪問 http://localhost:8080/people/search,返回結果爲:

{
    "_links": {
        "findByLastName": {
            "href": "http://localhost:8080/people/search/findByLastName{?name}",
            "templated": true
        },
        "self": {
            "href": "http://localhost:8080/people/search"
        }
    }
}

對的,findByLastName{?name} 就是我們在裏面新增的那個接口,那就順着這個意思咱們繼續來。

訪問 http://localhost:8080/people/search/findByLastName?name=folger,返回結果爲:

{
    "_embedded": {
        "people": [
            {
                "firstName": "jay",
                "lastName": "folger",
                "_links": {
                    "self": {
                        "href": "http://localhost:8080/people/3"
                    },
                    "person": {
                        "href": "http://localhost:8080/people/3"
                    }
                }
            }
        ]
    },
    "_links": {
        "self": {
            "href": "http://localhost:8080/people/search/findByLastName?name=folger"
        }
    }
}

與我們猜測無二。接口寫的返回是集合,所以就返回了一個集合。

之前還看到了這麼一條 link "href": "http://localhost:8080/people{?page,size,sort}"

有經驗的程序員一眼就肯定知道這些個參數都是幹什麼用的,是啊,就是分頁用的。

我們訪問這個 url : http://localhost:8080/people?page=0&size=4&sort=lastName,返回的結果爲:

{
    "_embedded": {
        "people": [
            {
                "firstName": "aaa",
                "lastName": "bbb",
                "_links": {
                    "self": {
                        "href": "http://localhost:8080/people/1"
                    },
                    "person": {
                        "href": "http://localhost:8080/people/1"
                    }
                }
            },
            {
                "firstName": "aaa",
                "lastName": "ccc",
                "_links": {
                    "self": {
                        "href": "http://localhost:8080/people/2"
                    },
                    "person": {
                        "href": "http://localhost:8080/people/2"
                    }
                }
            },
            {
                "firstName": "ccc",
                "lastName": "ccc",
                "_links": {
                    "self": {
                        "href": "http://localhost:8080/people/4"
                    },
                    "person": {
                        "href": "http://localhost:8080/people/4"
                    }
                }
            },
            {
                "firstName": "jay",
                "lastName": "folger",
                "_links": {
                    "self": {
                        "href": "http://localhost:8080/people/3"
                    },
                    "person": {
                        "href": "http://localhost:8080/people/3"
                    }
                }
            }
        ]
    },
    "_links": {
        "self": {
            "href": "http://localhost:8080/people"
        },
        "profile": {
            "href": "http://localhost:8080/profile/people"
        },
        "search": {
            "href": "http://localhost:8080/people/search"
        }
    },
    "page": {
        "size": 4,
        "totalElements": 4,
        "totalPages": 1,
        "number": 0
    }
}

從返回的數據我們可以看出: page 當然是頁數,size 就是每一頁的個數,sort 就是排序的字段,默認爲 asc。

這一波測試下來發現這樣封裝之後之前需要一大堆代碼才能實現的分頁,這裏只需要一個註解即可。妙啊妙不可言。

相關鏈接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章