Spring Data روی تکنولوژی های ذخیره و بازیابی اطلاعات یک لایه انتزاعی برای ما فراهم میکند که باعث میشود کد لاجیک برنامه مستقل از پیاده سازی Persistence توسعه داده شود و از این حیث فرآیند توسعه محصول را سریع تر خواهد کرد
Spring Data برای راحتی بیشتر یکسری annotation برای استفاده در نظر گرفته است که در این بخش با آنها آشنا میشویم
@NoRepositoryBean interface MyUtilityRepository<T, ID extends Serializable> extends CrudRepository<T, ID> { Optional<T> findById(ID id); }
حال اگر کلاس بالا فرزندی داشته باشد که Repository@ هم باشد NoRepositoryBean@ روی آن فرزند تاثیری ندارد :
@Repository interface PersonRepository extends MyUtilityRepository<Person, Long> {}
Param@ : میتوانیم پارامتر های کوئری را با این annotation ارسال کنیم :
به سینتکس name: توجه کنید که برای Param@ استفاده شده است
@Query("FROM Person p WHERE p.name = :name") Person findByName(@Param("name") String name);
Id@ : مشخص کننده Primary Key است :
class Person { @Id Long id; // ... }
Transient@ : فیلدهایی که با این annotation در کلاس model مشخص شده اند هنگام عملیات دیتابیسی خوانده و نوشته نمیشوند
class Person { // ... @Transient int age; // ... }
CreatedBy@
LastModifiedBy@
CreatedDate@
LastModifiedDate@
این annotation ها برای ثبت مشخصات کلاس های model استفاده میشود
public class Person { // ... @CreatedBy User creator; @LastModifiedBy User modifier; @CreatedDate Date createdAt; @LastModifiedDate Date modifiedAt; // ... }
باید توجه داشته باشیم که هنگام استفاده از این نوع annotation ها نیاز به استفاده از Spring Security داریم
Query@ : روی متد های Repository میتوانیم JPQL ست کنیم
@Query("SELECT COUNT(*) FROM Person p") long getPersonCount();
همینطور میتوان همراه با Param@ استفاده کرد :
@Query("FROM Person p WHERE p.name = :name") Person findByName(@Param("name") String name);
و یا از Native Query ها استفاده کرد :
@Query(value = "SELECT AVG(p.age) FROM person p", nativeQuery = true) int getAverageAge();
Procedure@ : از Repository بوسیله Spring Data JPA میتوان Stored Procedure ها را اجرا کرد. ابتدا بوسیله annotation های استاندارد JPA در داخل کلاس Entity باید Repository را تعریف کنیم :
@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 {}
سپس در Repository بوسیله پارامتر name آنر procedure را اجرا میکنیم
@Procedure(name = "count_by_name") long getCountByName(@Param("name") String name);
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
Modifying@ : اگر بخواهیم اطلاعات را تغییر بدهیم (مثل کوئری update) از این annotation روی متد Repository استفاده میکنیم
@Modifying @Query("UPDATE Person p SET p.name = :name WHERE p.id = :id") void changeName(@Param("id") long id, @Param("name") String name);
EnableJpaRepositories@ : اگر بخواهیم از Jpa Repository استفاده کنیم نیاز است در کلاس Configuration@ آنرا وارد کنیم و تمامی کلاس هایی که در زیر پکیج جاری کلاس وجود دارند اسکن شده و اگر Repository باشند آنها را در نظر میگیرد
@Configuration @EnableJpaRepositories class PersistenceJPAConfig {}
چنانچه بخواهیم میتوانیم پکیج مورد نظر را مشخص کنیم :
@Configuration @EnableJpaRepositories(basePackages = "org.baeldung.persistence.dao") class PersistenceJPAConfig {}
Annotation های مختص استفاده در MongoDB :
Document@ : مشخص کننده Domain Object است که در دیتابیس ذخیره خواهد شد
@Document class User {}
همینطور میتوانیم نام Collection را در صورت نیاز تعریف کنیم :
@Document(collection = "user") class User {}
*این annotation معادل Entity@ در JPA است
Field@ : معین کننده فیلد های کلاس Document@ است که در JPA معادل Column@ است
@Document class User { // ... @Field("email") String emailAddress; // ... }
Query@ : میتوانیم کوئری از نوع finder تعریف کنیم :
@Query("{ 'name' : ?0 }") List<User> findUsersByName(String name);
EnableMongoRepositories@ : با استفاده از یک کلاس Configuration@ مشخص میکنیم که Mongo Repository ها در پکیج جاری و زیر پکیج ها فعال و اسکن شوند :
@Configuration @EnableMongoRepositories class MongoConfig {}
و اگر بخواهیم آدرس پکیج را به طور مشخص تعیین کنیم بدین صورت اقدام میکنیم :
@Configuration @EnableMongoRepositories(basePackages = "org.baeldung.repository") class MongoConfig {}