打开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 。