Spring Data Annotations – Spring数据注解

最后修改: 2018年 5月 31日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.绪论

Spring Data provides an abstraction over data storage technologies. Therefore, our business logic code can be much more independent of the underlying persistence implementation. Also, Spring simplifies the handling of implementation-dependent details of data storage.

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

In this tutorial, we’ll see the most common annotations of the Spring Data, Spring Data JPA, and Spring Data MongoDB projects.

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

2. Common Spring Data Annotations

2.常见的Spring数据注解

2.1. @Transactional

2.1@Transactional

When we want to configure the transactional behavior of a method, we can do it with:

当我们想配置一个方法的交易行为时,我们可以用。

@Transactional
void pay() {}

If we apply this annotation on class level, then it works on all methods inside the class. However, we can override its effects by applying it to a specific method.

如果我们在类的层面上应用这个注解,那么它对类中的所有方法都有效。然而,我们可以通过将其应用于一个特定的方法来覆盖其效果。

It has many configuration options, which can be found in this article.

它有许多配置选项,可以在这篇文章中找到。

2.2. @NoRepositoryBean

2.2.@NoRepositoryBean

Sometimes we want to create repository interfaces with the only goal of providing common methods for the child repositories.

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

Of course, we don’t want Spring to create a bean of these repositories since we won’t inject them anywhere. @NoRepositoryBean does exactly this: when we mark a child interface of org.springframework.data.repository.Repository, Spring won’t create a bean out of it.

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

For example, if we want an Optional<T> findById(ID id) method in all of our repositories, we can create a base repository:

例如,如果我们想在所有的版本库中都有一个Optional<T> findById(ID id) 方法,我们可以创建一个基础版本库。

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

This annotation doesn’t affect the child interfaces; hence Spring will create a bean for the following repository interface:

这个注解并不影响子接口;因此Spring将为下面的存储库接口创建一个Bean。

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

Note, that the example above isn’t necessary since Spring Data version 2 which includes this method replacing the older T findOne(ID id).

注意,上面的例子在Spring Data第2版之后就没有必要了,它包括了这个方法,取代了旧的T findOne(ID id)

2.3. @Param

2.3. @Param

We can pass named parameters to our queries using @Param:

我们可以使用@Param向我们的查询传递命名参数。

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

Note, that we refer to the parameter with the :name syntax.

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

For further examples, please visit this article.

关于更多的例子,请访问这篇文章

2.4. @Id

2.4. @Id

@Id marks a field in a model class as the primary key:

@Id 在模型类中标记一个字段作为主键。

class Person {

    @Id
    Long id;

    // ...
    
}

Since it’s implementation-independent, it makes a model class easy to use with multiple data store engines.

由于它是独立于实现的,它使一个模型类很容易与多个数据存储引擎一起使用。

2.5. @Transient

2.5. @Transient

We can use this annotation to mark a field in a model class as transient. Hence the data store engine won’t read or write this field’s value:

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

class Person {

    // ...

    @Transient
    int age;

    // ...

}

Like @Id, @Transient is also implementation-independent, which makes it convenient to use with multiple data store implementations.

@Id一样,@Transient也是独立于实现的,这使得它能够方便地用于多个数据存储实现。

2.6. @CreatedBy, @LastModifiedBy, @CreatedDate, @LastModifiedDate

2.6.@CreatedBy, @LastModifiedBy, @CreatedDate, @LastModifiedDate

With these annotations, we can audit our model classes: Spring automatically populates the annotated fields with the principal who created the object, last modified it, and the date of creation, and last modification:

有了这些注解,我们就可以审计我们的模型类。Spring会自动将创建对象的委托人、最后一次修改对象的委托人以及创建和最后一次修改的日期填充到注释的字段中。

public class Person {

    // ...

    @CreatedBy
    User creator;
    
    @LastModifiedBy
    User modifier;
    
    @CreatedDate
    Date createdAt;
    
    @LastModifiedDate
    Date modifiedAt;

    // ...

}

Note, that if we want Spring to populate the principals, we need to use Spring Security as well.

注意,如果我们想让Spring来填充委托人,我们也需要使用Spring Security。

For a more thorough description, please visit this article.

如需更全面的描述,请访问这篇文章

3. Spring Data JPA Annotations

3.Spring Data JPA注释

3.1. @Query

3.1@Query

With @Query, we can provide a JPQL implementation for a repository method:

通过@Query,我们可以为存储库方法提供一个JPQL实现。

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

Also, we can use named parameters:

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

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

Besides, we can use native SQL queries, if we set the nativeQuery argument to true:

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

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

For more information, please visit this article.

欲了解更多信息,请访问这篇文章

3.2. @Procedure

3.2.@程序

With Spring Data JPA we can easily call stored procedures from repositories.

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

First, we need to declare the repository on the entity class using standard JPA annotations:

首先,我们需要使用标准的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 {}

After this, we can refer to it in the repository with the name we declared in the name argument:

之后,我们可以用我们在name参数中声明的名字在版本库中引用它。

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

3.3. @Lock

3.3.@Lock

We can configure the lock mode when we execute a repository query method:

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

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

The available lock modes:

可用的锁定模式。

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

3.4. @Modifying

3.4.@修改

We can modify data with a repository method if we annotate it with @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);

For more information, please visit this article.

欲了解更多信息,请访问这篇文章

3.5. @EnableJpaRepositories

3.5.@EnableJpaRepositories

To use JPA repositories, we have to indicate it to Spring. We can do this with @EnableJpaRepositories.

要使用JPA存储库,我们必须向Spring表明这一点。我们可以用@EnableJpaRepositories.来做这件事。

Note, that we have to use this annotation with @Configuration:

注意,我们必须将这个注解与@Configuration一起使用。

@Configuration
@EnableJpaRepositories
class PersistenceJPAConfig {}

Spring will look for repositories in the sub packages of this @Configuration class.

Spring将在这个@Configuration类的子包中寻找存储库。

We can alter this behavior with the basePackages argument:

我们可以通过basePackages参数来改变这种行为。

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

Also note, that Spring Boot does this automatically if it finds Spring Data JPA on the classpath.

还要注意的是,如果Spring Boot在classpath上找到Spring Data JPA,它就会自动进行这项工作。

4. Spring Data Mongo Annotations

4.Spring Data Mongo注解

Spring Data makes working with MongoDB much easier. In the next sections, we’ll explore the most basic features of Spring Data MongoDB.

Spring Data让与MongoDB的合作变得更加容易。在接下来的章节中,我们将探索Spring Data MongoDB的最基本功能。

For more information, please visit our article about Spring Data MongoDB.

欲了解更多信息,请访问我们的关于Spring Data MongoDB的文章

4.1. @Document

4.1. @Document

This annotation marks a class as being a domain object that we want to persist to the database:

这个注解标志着一个类是我们想要持久化到数据库的领域对象。

@Document
class User {}

It also allows us to choose the name of the collection we want to use:

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

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

Note, that this annotation is the Mongo equivalent of @Entity in JPA.

注意,这个注解相当于JPA中的@Entity的Mongo注解。

4.2. @Field

4.2.@Field

With @Field, we can configure the name of a field we want to use when MongoDB persists the document:

通过@Field,我们可以配置我们希望在MongoDB持久化文档时使用的字段名称。

@Document
class User {

    // ...

    @Field("email")
    String emailAddress;

    // ...

}

Note, that this annotation is the Mongo equivalent of @Column in JPA.

注意,这个注解相当于JPA中的@Column 的Mongo注释。

4.3. @Query

4.3@Query

With @Query, we can provide a finder query on a MongoDB repository method:

通过@Query,我们可以在MongoDB存储库方法上提供一个查找查询。

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

4.4. @EnableMongoRepositories

4.4.@EnableMongoRepositories

To use MongoDB repositories, we have to indicate it to Spring. We can do this with @EnableMongoRepositories.

要使用MongoDB存储库,我们必须向Spring表明这一点。我们可以通过@EnableMongoRepositories.来实现这一点。

Note, that we have to use this annotation with @Configuration:

注意,我们必须将这个注解与@Configuration一起使用。

@Configuration
@EnableMongoRepositories
class MongoConfig {}

Spring will look for repositories in the sub packages of this @Configuration class. We can alter this behavior with the basePackages argument:

Spring将在这个@Configuration类的子包中寻找存储库。我们可以通过basePackages参数来改变这种行为。

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

Also note, that Spring Boot does this automatically if it finds Spring Data MongoDB on the classpath.

还要注意的是,如果Spring Boot在classpath上发现Spring Data MongoDB,它就会自动这样做。

5. Conclusion

5.总结

In this article, we saw which are the most important annotations we need to deal with data in general, using Spring. In addition, we looked into the most common JPA and MongoDB annotations.

在这篇文章中,我们看到了哪些是我们在使用Spring处理数据时需要的最重要的注释。此外,我们还研究了最常见的JPA和MongoDB注解。

As usual, examples are available over on GitHub here for common and JPA annotations, and here for MongoDB annotations.

像往常一样,在GitHub上可以看到普通和JPA注释的例子这里,以及MongoDB注释的这里

Next »

Spring Bean Annotations

« Previous

Spring Scheduling Annotations