Spring Data Annotations


1.简介

Spring Data提供了对数据存储技术的抽象。因此,我们的业务逻辑代码可以更加独立于底层持久性实现。此外,Spring简化了对依赖于实现的数据存储细节的处理。

在本教程中,我们将看到Spring Data,Spring Data JPA和Spring Data MongoDB项目的最常见注释。

2.常见的Spring数据注释

2.1. @Transactional

当我们想要配置方法的事务行为时,我们可以使用:

@Transactional
void pay() {}

如果我们在类级别上应用此批注,那么它适用于类中的所有方法。但是,我们可以通过将其应用于特定方法来覆盖其效果。

2.2. @NoRepositoryBean

有时我们想要创建存储库接口,其唯一目标是为子存储库提供通用方法。

当然,我们不希望Spring创建这些存储库的bean,因为我们不会将它们注入任何地方。@NoRepositoryBean就是 这样做的:当我们标记org.springframework.data.repository.Repository的子接口时,Spring不会创建它的bean。

例如,如果我们想在所有存储库中使用Optional <T> findById(ID id) 方法,我们可以创建一个基本存储库:

@NoRepositoryBean
interface MyUtilityRepository<T, ID extends Serializable> extends CrudRepository<T, ID> {
    Optional<T> findById(ID id);
}

此注释不会影响子接口; 因此Spring将为以下存储库接口创建一个bean:

@Repository
interface PersonRepository extends MyUtilityRepository<Person, Long> {}

请注意,上面的示例不是必需的,因为包含此方法的Spring Data版本2替换了旧的T findOne(ID id)。

2.3. @Param

我们可以使用@Param将命名参数传递给我们的查询:

@Query("FROM Person p WHERE p.name = :name")
Person findByName(@Param("name") String name);

注意,我们使用:name 语法引用参数。

2.4. @ID

@Id 将模型类中的字段标记为主键:

class Person {

    @Id
    Long id;

    // ...

}

由于它与实现无关,因此它使模型类易于与多个数据存储引擎一起使用。

2.5.@Transient

我们可以使用此注释将模型类中的字段标记为瞬态。因此,数据存储引擎不会读取或写入此字段的值:

class Person {

    // ...

    @Transient
    int age;

    // ...

}

像@Id,@Transient 也是独立执行的,这使得与多个数据存储实现使用很方便。

2.6.@CreatedBy,@ LastModifiedBy,@ ManagingDate,@ LastModifiedDate

通过这些注释,我们可以审计我们的模型类:Spring自动使用创建对象的主体,最后修改它,创建日期和最后修改来填充带注释的字段:

public class Person {

    // ...

    @CreatedBy
    User creator;

    @LastModifiedBy
    User modifier;

    @CreatedDate
    Date createdAt;

    @LastModifiedDate
    Date modifiedAt;

    // ...

}

注意,如果我们希望Spring填充主体,我们也需要使用Spring Security。

3. Spring Data JPA Annotations

3.1. @Query

使用@Query,我们可以为存储库方法提供JPQL实现:

@Query("SELECT COUNT(*) FROM Person p")
long getPersonCount();

另外,我们可以使用命名参数:

@Query("FROM Person p WHERE p.name = :name")
Person findByName(@Param("name") String name);

此外,如果我们将nativeQuery 参数设置为true,我们可以使用本机SQL查询:

@Query(value = "SELECT AVG(p.age) FROM person p", nativeQuery = true)
int getAverageAge();

3.2. @Procedure

使用Spring Data JPA,我们可以轻松地从存储库调用存储过程。

首先,我们需要使用标准JPA注释在实体类上声明存储库:

@NamedStoredProcedureQueries({
    @NamedStoredProcedureQuery(
        name = "count_by_name",
        procedureName = "person.count_by_name",
        parameters = {
            @StoredProcedureParameter(
                mode = ParameterMode.IN,
                name = "name",
                type = String.class),
            @StoredProcedureParameter(
                mode = ParameterMode.OUT,
                name = "count",
                type = Long.class)
            }
    )
})

class Person {}

在此之后,我们可以在存储库中使用我们在name参数中声明的名称来 引用它:

@Procedure(name = "count_by_name")
long getCountByName(@Param("name") String name);

3.3. @Lock

我们可以在执行存储库查询方法时配置锁定模式:

@Lock(LockModeType.NONE)
@Query("SELECT COUNT(*) FROM Person p")
long getPersonCount();

可用的锁定模式:

  • READ
  • WRITE
  • OPTIMISTIC
  • OPTIMISTIC_FORCE_INCREMENT
  • PESSIMISTIC_READ
  • PESSIMISTIC_WRITE
  • PESSIMISTIC_FORCE_INCREMENT
  • NONE

3.4. @Modifying

如果我们使用@Modifying进行注释,我们可以使用存储库方法修改数据:

@Modifying
@Query("UPDATE Person p SET p.name = :name WHERE p.id = :id")
void changeName(@Param("id") long id, @Param("name") String name);

3.5.@EnableJpaRepositories

要使用JPA存储库,我们必须向Spring指出它。我们可以使用@EnableJpaRepositories来做到这一点。

注意,我们必须在@Configuration中使用此注释:

@Configuration
@EnableJpaRepositories
class PersistenceJPAConfig {}

Spring将在此@Configuration 类的子包中查找存储库。

我们可以使用basePackages 参数更改此行为:

@Configuration
@EnableJpaRepositories(basePackages = "org.baeldung.persistence.dao")
class PersistenceJPAConfig {}

另请注意,如果在类路径中找到Spring Data JPA,Spring Boot会自动执行此操作。

4. Spring Data Mongo Annotations

Spring Data使得使用MongoDB变得更加容易。在接下来的部分中,我们将探索Spring Data MongoDB的最基本功能。

有关更多信息,请访问我们关于Spring Data MongoDB的文章。

4.1.@Document

此批注将类标记为我们要保留到数据库的域对象:

@Document
class User {}

它还允许我们选择我们想要使用的集合的名称:

@Document(collection = "user")
class User {}

请注意,此注释是JPA中与@Entity 等效的Mongo 。

4.2. @Field

使用@Field,我们可以配置MongoDB持久保存文档时要使用的字段的名称:

@Document
class User {

    // ...

    @Field("email")
    String emailAddress;

    // ...

}

注意,这个注释是JPA 中@Column 的Mongo等价物。

4.3.@Query

使用@Query,我们可以在MongoDB存储库方法上提供查找器查询:

@Query("{ 'name' : ?0 }")
List<User> findUsersByName(String name);

4.4.@EnableMongoRepositories

要使用MongoDB存储库,我们必须向Spring指出它。我们可以使用@EnableMongoRepositories来做到这一点。

注意,我们必须在@Configuration中使用此注释:

@Configuration
@EnableMongoRepositories
class MongoConfig {}

Spring将在此@Configuration 类的子包中查找存储库。我们可以使用basePackages 参数更改此行为:

@Configuration
@EnableMongoRepositories(basePackages = "org.baeldung.repository")
class MongoConfig {}

另请注意,如果在类路径中找到Spring Data MongoDB,Spring Boot会自动执行此操作。