Spring Data 注解介绍

Spring Data是Spring 的一个子项目,用于简化数据库访问。Spring Data提供了对数据存储技术的抽象。使业务逻辑代码可以更加独立于底层的持久化实现。目前Spring Data支持NoSQL和关系数据库存储。

在本文中,我们将介绍Spring Data,Spring Data JPA和Spring Data MongoDB项目中最常见的注解。

1 常见的Spring Data注解

1.1 @Transactional

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

@Transactional
void pay() {}

如果我们在类级别上使用此注解,那么它适用于类中的所有方法。但是我们也可以通过对特定方法来单独设置。

1.2 @NoRepositoryBean

有时我们想要创建存储库接口,其唯一目标是为子存储库提供通用方法。也就是说,使用了该注解的接口不会被单独创建实例,只会作为其他接口的父接口而被使用。这个公共接口就需要这个注解@NoRepositoryBean来标识。

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

@NoRepositoryBean
interface MyUtilityRepository extends CrudRepository {
    Optional findById(ID id);
}

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

@Repository
interface PersonRepository extends MyUtilityRepository {}

1.3 @Param

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

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

也可以传递Collection参数:

@Query(value = "SELECT u FROM User u WHERE u.name IN :names")
List findUserByNameList(@Param("names") Collection names);

1.4 @ID

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

class Person {
 
    @Id
    Long id;
 
    // ...
     
}

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

1.5 @Transient

@Transient表示该属性并非一个到数据库表的字段的映射,ORM框架将忽略该属性。如果一个属性并非数据库表的字段映射,就务必将其标示为@Transient,数据存储引擎不会读取或写入此字段的值:

class Person {
 
    // ...
 
    @Transient
    int age;
 
    // ...
 
}

1.6 @CreatedBy,@ LastModifiedBy,@ ManagingDate,@ LastModifiedDate

通过这些注解可以为我们的数据模型添加一些审计信息。

public class Person {
 
    // ...
 
    @CreatedBy
    User creator;
     
    @LastModifiedBy
    User modifier;
     
    @CreatedDate
    Date createdAt;
     
    @LastModifiedDate
    Date modifiedAt;
 
    // ...
 
}

2 Spring Data JPA注解

2.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();

2.2 @Procedure

使用此注解我们可以轻松地从存储库调用存储过程。
首先,我们需要使用标准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);

2.3 @Lock

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

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

可用的锁模式:

  • READ
  • WRITE
  • OPTIMISTIC: 它和READ锁模式相同,JPA 2.0仍然支持READ锁模式,但明确指出在新应用程序中推荐使用OPTIMISTIC。
  • OPTIMISTIC_FORCE_INCREMENT:它和WRITE锁模式相同,JPA 2.0仍然支持WRITE锁模式,但明确指出在新应用程序中推荐使用OPTIMISTIC_FORCE_INCREMENT。
  • PESSIMISTIC_READ:只要事务读实体,实体管理器就锁定实体,直到事务完成锁才会解开,当你想使用重复读语义查询数据时使用这种锁模式,换句话说就是,当你想确保数据在连续读期间不被修改,这种锁模式不会阻碍其它事务读取数据。
  • PESSIMISTIC_WRITE:只要事务更新实体,实体管理器就会锁定实体,这种锁模式强制尝试修改实体数据的事务串行化,当多个并发更新事务出现更新失败几率较高时使用这种锁模式。 当事务读实体时,实体管理器就锁定实体,当事务结束时会增加实体的版本属性,即使实体没有修改。
  • PESSIMISTIC_FORCE_INCREMENT:
  • NONE: 无锁

2.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);

2.5 @EnableJpaRepositories

使用@EnableJpaRepositories注解来指定开启JPA存储库。注意,我们必须在@Configuration中使用此注释:

@Configuration
@EnableJpaRepositories
class PersistenceJPAConfig {}

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

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

3 Spring Data Mongo注解

3.1 @Document

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

@Document
class User {}

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

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

此注解类似于JPA中的@Entity。

3.2 @Field

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

@Document
class User {
 
    // ...
 
    @Field("email")
    String emailAddress;
 
    // ...
 
}

此注解类似于JPA中的@Column。

3.3 @Query

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

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

3.4 @EnableMongoRepositories

使用@EnableMongoRepositories注解来指定开启MongoDB存储库。类似于JPA中的@EnableJpaRepositories。

4 结论

在本文中,我们看到了使用Spring时我们需要处理数据的最主要的一些注解。此外,我们介绍了最常见的JPA和MongoDB注解。

你可能感兴趣的:(program)