29.3 JPA and Spring Data

Java Persistence API是一种标准技术,允许您将对象“映射”到关系数据库.spring-boot-starter-data-jpaPOM提供了一个快捷的方法开始.它提供了以下关键依赖:

  • Hibernate:最受欢迎的JPA实现之一.
  • Spring Data JPA:容易实现基于JPA的仓库.
  • Spring ORMs:Spring框架提供对核心ORM的支持.

Tip

我们不在这里提供太多关于JPA或Spring Data的细节.您可以参照spring.io网站的Accessing Data with JPA指南和阅读Spring Data JPAHibernate参考文档.

Entity Classes

传统上,JPA “Entity”类是在persistence.xml文件中配置的.在Spring Boot下,这个文件是没有必要,转而使用“实体扫描”方是. 默认情况下,在主要配置类所在包下(标注@EnableAutoConfiguration@SpringBootApplication注解的类)都会被扫描搜索.

标注@Entity、@embed或@MappedSuperclass注解的任何类都会被考虑为实体.一个典型的实体类像下面的例子:

  1. package com.example.myapp.domain;
  2. import java.io.Serializable;
  3. import javax.persistence.*;
  4. @Entity
  5. public class City implements Serializable {
  6. @Id
  7. @GeneratedValue
  8. private Long id;
  9. @Column(nullable = false)
  10. private String name;
  11. @Column(nullable = false)
  12. private String state;
  13. // ... additional members, often include @OneToMany mappings
  14. protected City() {
  15. // no-args constructor required by JPA spec
  16. // this one is protected since it shouldn't be used directly
  17. }
  18. public City(String name, String state) {
  19. this.name = name;
  20. this.country = country;
  21. }
  22. public String getName() {
  23. return this.name;
  24. }
  25. public String getState() {
  26. return this.state;
  27. }
  28. }

Tip

您可以使用@EntityScan注解自定义实体扫描路径.请参考Section79.4 Separate @Entity Definitions from Spring Configurationhow-to章节.

Spring Data JPA Repositories

Spring Data JPA仓库是您可以定义来访问数据的接口.JPA查询自动从你的方法名创建. 例如,CityRepository接口可能定义findAllByState(String state)方法来查询给定州下的所有城市.

对于更复杂的查询,您可以使用Spring Data的Query注解标注你的方法.

Spring Data仓库类通常继承RepositoryCrudRepository接口. 如果你使用自动配置,主要配置类所在包下(标注@EnableAutoConfiguration@SpringBootApplication注解的类)的仓库都会被扫描搜索到.

下图显示了典型的Spring Data仓库接口定义:

  1. package com.example.myapp.domain;
  2. import org.springframework.data.domain.*;
  3. import org.springframework.data.repository.*;
  4. public interface CityRepository extends Repository<City, Long> {
  5. Page<City> findAll(Pageable pageable);
  6. City findByNameAndCountryAllIgnoringCase(String name, String country);
  7. }

Tip

我们仅仅涉及到Spring Data JPA的表面, 要获取完整的信息,请参考Spring Data JPA reference documentation.

Creating and Dropping JPA Databases

默认情况下,只在你使用嵌入式数据库(H2、HSQL或Derby)时会自动创建JPA数据库.您可以通过使用spring.jpa.*属性显式地配置JPA选项. 例如,为了能自动创建和删除表,您可以添加以下行到你的application.properties:

  1. spring.jpa.hibernate.ddl-auto=create-drop

Note

Hibernate对应的内部属性名为(如果你碰巧记得更好)hibernate.hbm2dll.auto.你可以设置它,连同其他Hibernate原生属性,通过使用spring.jpa.properties.*属性(前缀在他们被增加到实体管理器之前删除了). 下面一行显示为Hibernate设置JPA属性的示例:

  1. spring.jpa.properties.hibernate.globally_quoted_identifiers=true

前面示例中的行为hibernate_globally_quoted_identifier属性传递了true值到Hibernate的实体管理器.

默认情况下,DDL执行(或验证)被延迟直到ApplicationContext已经启动.还存在spring.jpa.generate-ddl标记,但它在Hibernate自动配置激活状态下不起作用,因为ddl-auto设置更细粒度.

Open EntityManager in View

如果您正在运行一个web应用程序,Spring Boot默认注册OpenEntityManagerInViewInterceptor应用“Open EntityManager in View”模式,允许延迟加载在web视图. 如果您不想要这么做,您应该在你的application.properties文件中设置spring.jpa.open-in-viewfalse.