در این بخش خواهیم دید که چگونه از Spring Data JPA در یک پروژه استفاده کنیم و کانفیگ های کاملتری برای لایه Persistence را بررسی خواهیم کرد
ابتدا وابستگی ها را اضافه میکنیم :
<dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-jpa</artifactId> <version>2.1.6.RELEASE</version> </dependency>
ایجاد لایه DAO بدون پیاده سازی :
معمولا برای ایجاد لایه DAO نیاز به کدنویسی اضافی داریم که باید آنرا ساده تر کنیم هر چقدر ایجاد لایه ها ساده تر شود نگهداری و توسعه و تغییرات آتی در محصول ساده تر و توسعه پذیرتر خواهد بود
Spring Data کمک میکند که این لایه ایجاد شود و کد های پیاده سازی حذف گردند تنها نیاز است از اینترفیس DAO ارث بری کنیم و کلاس ما دارای ویژگی های CRUD خواهد بود
کوئری ها و متد های دسترسی سفارشی :
با پیاده سازی یکی از اینترفیس های Repository کلاس DAO دارای متدهای ساده ای برای عملیات CRUD میشود و برای تعریف دسترسی های خاص تر و پیچیده تر Spring JPA انتخاب های کاملتری را ارائه میدهد :
- به سادگی میتوان یک متد جدید در اینترفیس تعریف کرد
- با استفاده از Query@ میتوان یک JPQ تعریف کرد
- با استفاده از امکانات پیشرفته تر و QueryDSL در Spring Data
- تعریف کوئری دلخواه با استفاده از ویژگی JPA Named Query
*آخرین روش این ضعف را دارد که درگیر تنظیمات XML یا سنگین کردن کلاس با کوئری ها میشود
* QueryDSL شبیه به استفاده از JPA Criteria است اما ساده تر و منعطف تر
کوئری های سفارشی اتوماتیک :
وقتی با Spring Data یک پیاده سازی از اینترفیس های Repository داشته باشیم بصورت اتوماتیک کوئری هایی بر اساس نام خواهیم داشت مثلا اگر یک اینترفیس DAO داشته باشیم و کلاس Entity ما یک فیلد بنام name داشته باشد ما میتوانیم یک متد بنام findByName ایجاد کنیم و اتوماتیک کوئری برای آن ساخته میشود و میتواند یک Entity بر اساس name را از دیتابیس خوانده و برگرداند :
public interface IFooDAO extends JpaRepository<Foo, Long> { Foo findByName(String name); }
در هنگام ساخت کوئری اگر آن فیلد موجود نبود خطای IllegalArgumentException را دریافت خواهیم کرد :
java.lang.IllegalArgumentException: No property nam found for type class org.rest.model.Foo
میتوان کوئری های دلخواهی را با Query@ ایجاد کنیم :
@Query("SELECT f FROM Foo f WHERE LOWER(f.name) = LOWER(:name)") Foo retrieveByName(@Param("name") String name);
برای مشاهده موارد استفاده پیشرفته تر از پارامتر ها و همچنین SpEL از این لینک مشاهده کنید
تنظیمات Transaction :
پیاده سازی واقعی از Spring Data Managed DAO از دید ما پنهان است و ما نمیتوانیم مستقیما با آن کار کنیم و در کلاسی مانند SimpleJpaRepository بوسیله annotation ست شده است
در سطح کلاس با استفاده از Transactional@ که یک read-only annotation است میتوان تنظیمات Transaction را ست کرد که به ازای هر متد میتوان آنرا تغییر داد و حالت پیش فرضی که در سطح کلاس بود override شود
انتقال Exception :
از آنجا که ما از ORM Template ها مانند JpaTemplate و HibernateTemplate استفاده نمیکنیم ولی همچنان میتوانیم Exception ها را با کمک Repository@ انتقال را فعال کنیم این annotation یک Bean را جهت پردازش و هدایت خطاهای آتی رخ داده شده Repository@ ها توسط نمونه ای از PersistenceExceptionTranslator در سطح Container اعمال میکند
در مثال زیر عمل انتقال Exception را در یک تست انجام داده ایم :
@Test(expected = DataIntegrityViolationException.class) public void givenFooHasNoName_whenInvalidEntityIsCreated_thenDataException() { service.create(new Foo()); }
این انتقال توسط مکانیزم Proxy انجام میشود
تنظیم فعال سازی Spring JPA repository :
با قرار دادن EnableJpaRepositories@ در پکیجی که در برگیرنده DAO ها است میتوان Spring JPA Repository را فعال کرد :
@EnableJpaRepositories(basePackages = "com.baeldung.jpa.dao") public class PersistenceConfig { ... }
روش XML :
<jpa:repositories base-package="org.rest.dao.spring" />
Spring Data از PersistenceContext@ که جزء JPA Annotation است حمایت میکند که EntityManager را به Spring Factory Bean ای (JpaRepositoryFactoryBean) که مسول پیاده سازی DAO واقعی است، مرتبط میکند و اگر تنظیماتی در فایل XML ست کرده بودیم نیاز است که آنرا ImportResource@ کنیم
@Configuration @EnableTransactionManagement @ImportResource( "classpath*:*springDataConfig.xml" ) public class PersistenceJPAConfig{ ... }
استفاده از Spring Boot :
میتوانیم از Spring Boot Starter Data JPA استفاده کنیم که تنظیمات اتوماتیک DataSource را داراست
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> <version>2.1.3.RELEASE</version> </dependency>
در اینصورت تنظیمات استاندارد و اولیه راه اندازی Spring Data JPA برای استفاده آماده است و کافی است اطلاعات اتصال به دیتابیس را در application.properties وارد کنیم :
spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 spring.datasource.username=sa spring.datasource.password=sa