原文: http://zetcode.com/springboot/jparepository/

SpringBoot JpaRepository教程展示了如何使用JpaRepository在 Spring Boot 应用中管理数据。

Spring 是流行的 Java 应用框架。 Spring Boot 致力于以最小的努力创建独立的,基于生产级别的基于 Spring 的应用。

Spring Data

Spring Data 是用于数据访问的基于 Spring 的编程模型。 它减少了使用数据库和数据存储所需的代码量。 它由几个模块组成。 Spring Data JPA 简化了使用 JPA 技术的 Spring 应用的开发。

使用 Spring Data,我们为应用中的每个域实体定义了一个存储库接口。 存储库包含用于执行 CRUD 操作,对数据进行排序和分页的方法。 @Repository是标记注解,指示基础接口是存储库。 通过扩展特定的存储库接口(例如CrudRepositoryPagingAndSortingRepositoryJpaRepository)来创建存储库。

Spring Data 已与 Spring MVC 控制器进行了高级集成,并提供了从存储库方法名称派生的动态查询。

JpaRepository

JpaRepositoryRepository的 JPA 特定扩展。 它包含CrudRepositoryPagingAndSortingRepository的完整 API。 因此,它包含用于基本 CRUD 操作的 API,以及用于分页和排序的 API。

Spring Boot JpaRepository 示例

以下 Spring Boot 应用使用JpaRepository管理City实体。 数据保存在 H2 数据库中。 该应用是一个控制台程序。

  1. pom.xml
  2. src
  3. ├───main
  4. ├───java
  5. └───com
  6. └───zetcode
  7. Application.java
  8. MyRunner.java
  9. ├───model
  10. City.java
  11. └───repository
  12. CityRepository.java
  13. └───resources
  14. application.properties
  15. └───test
  16. └───java

这是项目结构。

pom.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
  5. http://maven.apache.org/xsd/maven-4.0.0.xsd">
  6. <modelVersion>4.0.0</modelVersion>
  7. <groupId>com.zetcode</groupId>
  8. <artifactId>springbootjparepository</artifactId>
  9. <version>1.0-SNAPSHOT</version>
  10. <packaging>jar</packaging>
  11. <properties>
  12. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  13. <maven.compiler.source>11</maven.compiler.source>
  14. <maven.compiler.target>11</maven.compiler.target>
  15. </properties>
  16. <parent>
  17. <groupId>org.springframework.boot</groupId>
  18. <artifactId>spring-boot-starter-parent</artifactId>
  19. <version>2.1.1.RELEASE</version>
  20. </parent>
  21. <dependencies>
  22. <dependency>
  23. <groupId>org.springframework.boot</groupId>
  24. <artifactId>spring-boot-starter-data-jpa</artifactId>
  25. </dependency>
  26. <dependency>
  27. <groupId>com.h2database</groupId>
  28. <artifactId>h2</artifactId>
  29. <scope>runtime</scope>
  30. </dependency>
  31. </dependencies>
  32. <build>
  33. <plugins>
  34. <plugin>
  35. <groupId>org.springframework.boot</groupId>
  36. <artifactId>spring-boot-maven-plugin</artifactId>
  37. </plugin>
  38. </plugins>
  39. </build>
  40. </project>

这是 Maven 构建文件。 spring-boot-starter-data-jpa是将 Spring Data JPA 与 Hibernate 结合使用的入门工具。

resources/application.properties

  1. spring.main.banner-mode=off
  2. logging.pattern.console=%clr(%d{yy-MM-dd E HH:mm:ss.SSS}){blue} %clr(%-5p) %clr(%logger{0}){blue} %clr(%m){faint}%n

application.properties是主要的 Spring Boot 配置文件。 使用spring.main.banner-mode属性,我们可以关闭 Spring 横幅。 logging.pattern.console定义控制台的日志模式。

com/zetcode/model/City.java

  1. package com.zetcode.model;
  2. import java.util.Objects;
  3. import javax.persistence.Entity;
  4. import javax.persistence.GeneratedValue;
  5. import javax.persistence.GenerationType;
  6. import javax.persistence.Id;
  7. import javax.persistence.Table;
  8. @Entity
  9. @Table(name = "cities")
  10. public class City {
  11. @Id
  12. @GeneratedValue(strategy = GenerationType.AUTO)
  13. private Long id;
  14. private String name;
  15. private int population;
  16. public City() {
  17. }
  18. public City(String name, int population) {
  19. this.name = name;
  20. this.population = population;
  21. }
  22. public Long getId() {
  23. return id;
  24. }
  25. public void setId(Long id) {
  26. this.id = id;
  27. }
  28. public String getName() {
  29. return name;
  30. }
  31. public void setName(String name) {
  32. this.name = name;
  33. }
  34. public int getPopulation() {
  35. return population;
  36. }
  37. public void setPopulation(int population) {
  38. this.population = population;
  39. }
  40. @Override
  41. public int hashCode() {
  42. int hash = 7;
  43. hash = 79 * hash + Objects.hashCode(this.id);
  44. hash = 79 * hash + Objects.hashCode(this.name);
  45. hash = 79 * hash + this.population;
  46. return hash;
  47. }
  48. @Override
  49. public boolean equals(Object obj) {
  50. if (this == obj) {
  51. return true;
  52. }
  53. if (obj == null) {
  54. return false;
  55. }
  56. if (getClass() != obj.getClass()) {
  57. return false;
  58. }
  59. final City other = (City) obj;
  60. if (this.population != other.population) {
  61. return false;
  62. }
  63. if (!Objects.equals(this.name, other.name)) {
  64. return false;
  65. }
  66. return Objects.equals(this.id, other.id);
  67. }
  68. @Override
  69. public String toString() {
  70. var builder = new StringBuilder();
  71. builder.append("City{id=").append(id).append(", name=")
  72. .append(name).append(", population=")
  73. .append(population).append("}");
  74. return builder.toString();
  75. }
  76. }

这是City实体。 它包含以下属性:idnamepopulation

com/zetcode/repository/CityRepository.java

  1. package com.zetcode.repository;
  2. import com.zetcode.model.City;
  3. import org.springframework.data.jpa.repository.JpaRepository;
  4. import org.springframework.stereotype.Repository;
  5. @Repository
  6. public interface CityRepository extends JpaRepository<City, Long> {
  7. }

CityRepositoryJpaRepository延伸。 它提供了实体的类型及其主键。

注意:在Java企业应用中,定义与存储库一起使用的服务层是一个好习惯。 为简单起见,我们跳过服务层。

com/zetcode/MyRunner.java

  1. package com.zetcode;
  2. import com.zetcode.model.City;
  3. import com.zetcode.repository.CityRepository;
  4. import org.slf4j.Logger;
  5. import org.slf4j.LoggerFactory;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.boot.CommandLineRunner;
  8. import org.springframework.data.domain.Sort;
  9. import org.springframework.stereotype.Component;
  10. @Component
  11. public class MyRunner implements CommandLineRunner {
  12. private static final Logger logger = LoggerFactory.getLogger(MyRunner.class);
  13. @Autowired
  14. private CityRepository cityRepository;
  15. @Override
  16. public void run(String... args) throws Exception {
  17. cityRepository.save(new City("Bratislava", 432000));
  18. cityRepository.save(new City("Budapest", 1759000));
  19. cityRepository.save(new City("Prague", 1280000));
  20. cityRepository.save(new City("Warsaw", 1748000));
  21. cityRepository.save(new City("Los Angeles", 3971000));
  22. cityRepository.save(new City("New York", 8550000));
  23. cityRepository.save(new City("Edinburgh", 464000));
  24. logger.info("# of cities: {}", cityRepository.count());
  25. logger.info("All cities unsorted:");
  26. var cities = cityRepository.findAll();
  27. logger.info("{}", cities);
  28. logger.info("------------------------");
  29. logger.info("All cities sorted by name in descending order");
  30. var sortedCities = cityRepository.findAll(new Sort(Sort.Direction.DESC, "name"));
  31. logger.info("{}", sortedCities);
  32. logger.info("------------------------");
  33. logger.info("Deleting all cities");
  34. cityRepository.deleteAllInBatch();
  35. logger.info("# of cities: {}", cityRepository.count());
  36. }
  37. }

MyRunner中,我们使用JpaRepository的各种方法。

  1. @Autowired
  2. private CityRepository cityRepository;

我们将CityRepository注入cityRepository字段。

  1. cityRepository.save(new City("Bratislava", 432000));

使用save()插入一个新城市。

  1. logger.info("# of cities: {}", cityRepository.count());

我们用count()计算城市数。

  1. logger.info("All cities unsorted:");
  2. var cities = cityRepository.findAll();
  3. logger.info("{}", cities);

使用findAll(),我们可以到达所有城市。

  1. logger.info("All cities sorted by name in descending order");
  2. var sortedCities = cityRepository.findAll(new Sort(Sort.Direction.DESC, "name"));
  3. logger.info("{}", sortedCities);

通过将Sort对象传递给findAll()方法,我们得到了所有城市的降序排列。

  1. logger.info("Deleting all cities");
  2. cityRepository.deleteAllInBatch();

我们使用deleteAllInBatch()批量删除所有城市。

com/zetcode/Application.java

  1. package com.zetcode;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. @SpringBootApplication
  5. public class Application {
  6. public static void main(String[] args) {
  7. SpringApplication.run(Application.class, args);
  8. }
  9. }

Application设置 Spring Boot 应用。

  1. ...
  2. 19-06-25 Tue 12:47:14.593 INFO MyRunner # of cities: 7
  3. 19-06-25 Tue 12:47:14.593 INFO MyRunner All cities unsorted:
  4. 19-06-25 Tue 12:47:14.652 INFO MyRunner [City{id=1, name=Bratislava, population=432000}, City{id=2, name=Budapest, population=1759000}, City{id=3, name=Prague, population=1280000}, City{id=4, name=Warsaw, population=1748000}, City{id=5, name=Los Angeles, population=3971000}, City{id=6, name=New York, population=8550000}, City{id=7, name=Edinburgh, population=464000}]
  5. 19-06-25 Tue 12:47:14.652 INFO MyRunner ------------------------
  6. 19-06-25 Tue 12:47:14.652 INFO MyRunner All cities sorted by name in descending order
  7. 19-06-25 Tue 12:47:14.667 INFO MyRunner [City{id=4, name=Warsaw, population=1748000}, City{id=3, name=Prague, population=1280000}, City{id=6, name=New York, population=8550000}, City{id=5, name=Los Angeles, population=3971000}, City{id=7, name=Edinburgh, population=464000}, City{id=2, name=Budapest, population=1759000}, City{id=1, name=Bratislava, population=432000}]
  8. 19-06-25 Tue 12:47:14.668 INFO MyRunner ------------------------
  9. 19-06-25 Tue 12:47:14.668 INFO MyRunner Deleting all cities
  10. 19-06-25 Tue 12:47:14.681 INFO MyRunner # of cities: 0
  11. ...

这是一个示例输出。

在本教程中,我们使用JpaRepository管理了应用数据。 您可能也对相关教程感兴趣: Spring Boot CrudRepository教程Spring Boot Data JPA @Query教程Spring Boot Data JPA @NamedQuery教程Java 教程

列出所有 Spring Boot 教程