Перейти к основному содержимому

Аннотации данных Spring

· 6 мин. чтения

1. Введение

Spring Data обеспечивает абстракцию над технологиями хранения данных. Следовательно, наш код бизнес-логики может быть гораздо более независимым от базовой реализации постоянства. Кроме того, Spring упрощает обработку деталей хранения данных, зависящих от реализации.

В этом руководстве мы увидим наиболее распространенные аннотации проектов Spring Data, Spring Data JPA и Spring Data MongoDB.

2. Общие аннотации данных Spring

2.1. @транзакционный

Когда мы хотим настроить транзакционное поведение метода , мы можем сделать это с помощью:

@Transactional
void pay() {}

Если мы применим эту аннотацию на уровне класса, то она будет работать со всеми методами внутри класса. Однако мы можем переопределить его эффекты, применив его к определенному методу.

Имеет множество вариантов настройки, с которыми можно ознакомиться в этой статье .

2.2. @NoRepositoryBean

Иногда мы хотим создать интерфейсы репозитория с единственной целью предоставления общих методов для дочерних репозиториев .

Конечно, мы не хотим, чтобы Spring создавал bean-компонент этих репозиториев, поскольку мы не будем их никуда внедрять. @NoRepositoryBean делает именно это: когда мы помечаем дочерний интерфейс org.springframework.data.repository.Repository , Spring не будет создавать из него компонент.

Например, если нам нужен метод 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 :

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

Обратите внимание, что мы обращаемся к параметру с синтаксисом :name .

Дополнительные примеры см . в этой статье .

2.4. @Идентификатор

@Id помечает поле в классе модели как первичный ключ:

class Person {

@Id
Long id;

// ...

}

Поскольку он не зависит от реализации, он упрощает использование класса модели с несколькими механизмами хранения данных.

2.5. @транзиент

Мы можем использовать эту аннотацию, чтобы пометить поле в классе модели как временное. Следовательно, механизм хранилища данных не будет читать или записывать значение этого поля:

class Person {

// ...

@Transient
int age;

// ...

}

Как и @Id , @Transient также не зависит от реализации, что делает его удобным для использования с несколькими реализациями хранилища данных.

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

С помощью этих аннотаций мы можем проверять наши классы моделей: Spring автоматически заполняет аннотированные поля принципалом, создавшим объект, последним его изменением, датой создания и последней модификацией:

public class Person {

// ...

@CreatedBy
User creator;

@LastModifiedBy
User modifier;

@CreatedDate
Date createdAt;

@LastModifiedDate
Date modifiedAt;

// ...

}

Обратите внимание: если мы хотим, чтобы Spring заполнил принципы, нам также нужно использовать Spring Security.

Более подробное описание можно найти в этой статье .

3. Аннотации Spring Data JPA

3.1. @Запрос

С помощью @Query мы можем предоставить реализацию JPQL для метода репозитория:

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

Также мы можем использовать именованные параметры:

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

Кроме того, мы можем использовать нативные SQL-запросы, если установим для аргумента nativeQuery значение true :

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

Для получения дополнительной информации посетите эту статью .

3.2. @Процедура

С помощью 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 {}

После этого мы можем обратиться к нему в репозитории с именем, которое мы объявили в аргументе имени :

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

3.3. @Замок

Мы можем настроить режим блокировки при выполнении метода запроса репозитория:

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

Доступные режимы блокировки:

  • ЧИТАТЬ
  • ЗАПИСЫВАТЬ
  • ОПТИМИСТИЧНЫЙ
  • ОПТИМИСТИЧЕСКИЙ_FORCE_INCREMENT
  • PESSIMISTIC_READ
  • PESSIMISTIC_WRITE
  • PESSIMISTIC_FORCE_INCREMENT
  • НИКТО

3.4. @Изменение

Мы можем изменить данные с помощью метода репозитория, если аннотируем их с помощью @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 = "com.foreach.persistence.dao")
class PersistenceJPAConfig {}

Также обратите внимание, что Spring Boot делает это автоматически, если находит Spring Data JPA в пути к классам.

4. Аннотации Spring Data Mongo

Spring Data значительно упрощает работу с MongoDB. В следующих разделах мы рассмотрим самые основные функции Spring Data MongoDB.

Для получения дополнительной информации, пожалуйста, посетите нашу статью о Spring Data MongoDB .

4.1. @Документ

Эта аннотация помечает класс как объект домена, который мы хотим сохранить в базе данных:

@Document
class User {}

Это также позволяет нам выбрать имя коллекции, которую мы хотим использовать:

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

Обратите внимание, что эта аннотация является эквивалентом Mongo для @Entity в JPA.

4.2. @Поле

С помощью @Field мы можем настроить имя поля, которое мы хотим использовать, когда MongoDB сохраняет документ:

@Document
class User {

// ...

@Field("email")
String emailAddress;

// ...

}

Обратите внимание, что эта аннотация является эквивалентом @Column в Mongo в JPA.

4.3. @Запрос

С помощью @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 = "com.foreach.repository")
class MongoConfig {}

Также обратите внимание, что Spring Boot делает это автоматически, если находит Spring Data MongoDB в пути к классам.

5. Вывод

В этой статье мы увидели, какие аннотации наиболее важны для работы с данными в целом с использованием Spring. Кроме того, мы изучили наиболее распространенные аннотации JPA и MongoDB.

Как обычно, примеры доступны на GitHub здесь для общих аннотаций и аннотаций JPA, а здесь для аннотаций MongoDB.