打開IDEA -> Create New Projecthtml
package com.example.demo.entity; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; @Entity public class Customer { @Id @GeneratedValue private Long id; private String firstName; private String lastName; protected Customer() { } public Customer(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } @Override public String toString() { return "Customer{" + "id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + '}'; } }
建立與實體對應的Repositoryjava
package com.example.demo.repository; import com.example.demo.entity.Customer; import org.springframework.data.repository.CrudRepository; import java.util.List; public interface CustomerRepository extends CrudRepository<Customer, Long> { List<Customer> findByLastName(String lastName); }
經過繼承CrudRepository
繼承幾種增刪改查方法,也能夠經過方法名支定義其餘查詢方法。web
package com.example.demo; import com.example.demo.entity.Customer; import com.example.demo.repository.CustomerRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; @SpringBootApplication public class SpringDataJpaDemoApplication { public static final Logger log = LoggerFactory.getLogger(SpringDataJpaDemoApplication.class); public static void main(String[] args) { SpringApplication.run(SpringDataJpaDemoApplication.class, args); } @Bean public CommandLineRunner demo(CustomerRepository repository) { return (args -> { repository.save(new Customer("Jack", "Bauer")); repository.save(new Customer("Chloe", "Brian")); repository.save(new Customer("Kim", "Bauer")); repository.save(new Customer("David", "Palmer")); repository.save(new Customer("Michelle", "Dessler")); log.info("Customer found with save() finish"); log.info("Customer found with findAll()"); log.info("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); for (Customer customer : repository.findAll()) { log.info(customer.toString()); } log.info(""); repository.findById(1L).ifPresent(customer -> { log.info("Customer found with findById()"); log.info("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); log.info(customer.toString()); log.info(""); }); log.info("Customer found with findByLastName('findByLastName')"); log.info("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); repository.findByLastName("Bauer").forEach(bauer -> { log.info(bauer.toString()); }); log.info(""); }); } }
運行程序,經過 log 查看效果spring
pom.xml 添加依賴apache
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-rest</artifactId> </dependency> </dependencies> </project>
package com.example.demo.entity; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @Entity public class Person { @Id @GeneratedValue(strategy = GenerationType.AUTO) private long id; private String firstName; private String lastName; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } }
package com.example.demo.repository; import com.example.demo.entity.Person; import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.query.Param; import org.springframework.data.rest.core.annotation.RepositoryRestResource; import java.util.List; @RepositoryRestResource public interface PersonRepository extends PagingAndSortingRepository<Person, Long> { List<Person> findPersonByLastName(@Param("name") String name); }
此repository是一個接口,容許您執行涉及Person對象的各類操做。它經過繼承Spring Data Commons中定義的PagingAndSortingRepository
接口來獲取這些操做mvc
在運行時,Spring Data REST將自動建立此接口的實現。而後它將使用@RepositoryRestResource
註解指導Spring MVC建立RESTful端點/persons。app
測試程序less
首先看到頂層服務curl
curl http://localhost:8080/ { "_links" : { "customers" : { "href" : "http://localhost:8080/customers" }, "persons" : { "href" : "http://localhost:8080/persons{?page,size,sort}", "templated" : true }, "profile" : { "href" : "http://localhost:8080/profile" } } }
Spring Data REST使用 HAL格式進行JSON輸出。它很是靈活,能夠方便地提供與所服務數據相鄰的連接。
curl http://localhost:8080/persons { "_embedded" : { "persons" : [ ] }, "_links" : { "self" : { "href" : "http://localhost:8080/persons{?page,size,sort}", "templated" : true }, "profile" : { "href" : "http://localhost:8080/profile/persons" }, "search" : { "href" : "http://localhost:8080/persons/search" } }, "page" : { "size" : 20, "totalElements" : 0, "totalPages" : 0, "number" : 0 } }
能夠看到customers的也跟着顯示出來了,咱們能夠經過註釋隱藏,固然也能夠全局隱藏:maven
Spring Data REST使用RepositoryDetectionStrategy
來肯定是否將存儲庫導出爲REST資源。的RepositoryDiscoveryStrategies
列舉包括如下值:
Name | Description |
---|---|
DEFAULT | 默認,ANNOTATION + VISIBILITY |
ALL | 公開全部Repository |
ANNOTATION | 公開@RepositoryRestResource和@RestResource註解的Repository,除非exported設置爲false |
VISIBILITY | 暴露全部public修飾的Repository |
建立配置類
package com.example.demo.config; import org.springframework.data.rest.core.config.RepositoryRestConfiguration; import org.springframework.data.rest.core.mapping.RepositoryDetectionStrategy; import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurer; import org.springframework.stereotype.Component; @Component public class RestConfigurer implements RepositoryRestConfigurer { @Override public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) { config.setRepositoryDetectionStrategy(RepositoryDetectionStrategy.RepositoryDetectionStrategies.ANNOTATED); } }
測試
curl http://localhost:8080/ { "_links" : { "persons" : { "href" : "http://localhost:8080/persons{?page,size,sort}", "templated" : true }, "profile" : { "href" : "http://localhost:8080/profile" } } }
Pageable
是一個由 Spring 定義的接口,它擁有一個實現 PageRequest。讓咱們看看如何建立一個 PageRequest。
Pageable pageable = PageRequest.of(0, 10); Page<Employee> page = repository.findAll(pageable); // 也能夠簡單一點 Page<Employee> page = repository.findAll(PageRequest.of(0, 10));
表示請求第一頁10個數據。
若是咱們要訪問下一頁,咱們能夠每次增長頁碼。
PageRequest.of(1, 10); PageRequest.of(2, 10); PageRequest.of(3, 10); ...
Spring Data JPA 提供一個Sort
對象提供排序機制。讓咱們看一下排序的方式。
repository.findAll(Sort.by("fistName")); repository.findAll(Sort.by("fistName").ascending().and(Sort.by("lastName").descending());
Pageable pageable = PageRequest.of(0, 20, Sort.by("firstName")); Pageable pageable = PageRequest.of(0, 20, Sort.by("fistName").ascending().and(Sort.by("lastName").descending());
QueryByExampleExecutor
SpringData JPA 爲了實現 "Domain Driven Design" 中的規範概念,提供了一些列的 Specification 接口,其中最經常使用的即是 :JpaSpecificationExecutor。
使用 SpringData JPA 構建複雜查詢(join操做,彙集操做等等)都是依賴於 JpaSpecificationExecutor 構建的 Specification 。