في إصدار بيانات الربيع القادم ، الذي يحمل الاسم الرمزي Lovelace ، سنقوم بتضمين وحدة جديدة: Spring Data JDBC .
الفكرة وراء Spring Data JDBC هي توفير الوصول إلى قواعد البيانات العلائقية دون استخدام كل تعقيد JPA .
تقدم JPA ميزات مثل التحميل البطيء ، والتخزين المؤقت ، وتتبع التغيير (التتبع القذر). على الرغم من حقيقة أن هذه الميزات رائعة جدًا ، إذا كنت حقًا بحاجة إليها ، بالطبع ، فإنها يمكن أن تعقد بشكل كبير فهم منطق الوصول إلى البيانات.
يمكن أن تؤدي آلية التحميل البطيء فجأة إلى تنفيذ طلبات كثيفة الاستخدام للموارد ، أو حتى تفشل مع استثناء. يمكن أن يقف التخزين المؤقت في طريقك عندما تقرر مقارنة نسختين من الكيان ، إلى جانب التغييرات في التتبع يجعل من الصعب فهم في أي مرحلة سيتم فيها تنفيذ جميع عمليات قاعدة البيانات فعليًا؟
يركز Spring Data JDBC على نموذج أبسط بكثير . لن يكون هناك تخزين مؤقت أو تتبع للتغيير أو تحميل بطيء. بدلاً من ذلك ، سيتم تنفيذ استعلامات SQL إذا وفقط إذا قمت باستدعاء طريقة المخزون. سيتم تحميل النتيجة التي تم إرجاعها بالكامل في الذاكرة بعد تنفيذ الطريقة. لن تكون هناك آلية "جلسة" أو كائنات وكيل للكيانات. وكل هذا من شأنه أن يجعل Spring Data JDBC أداة أبسط وأكثر سهولة للوصول إلى البيانات.
بالطبع ، يُترجم هذا النهج المبسط إلى عدد من القيود ، والتي سنناقشها في المشاركات القادمة. الإصدار القادم هو الإصدار الأول من المكتبة ، لدينا العديد من الخطط والأفكار التي نريد تنفيذها ، ولكن علينا تأجيلها لمنحك الفرصة لبدء استخدام Spring Data JDBC في أقرب وقت ممكن.
مثال
للبدء ، نحتاج إلى تحديد الكيان:
class Customer { @Id Long id; String firstName; LocalDate dob; }
يرجى ملاحظة أننا لا نحدد أي حرف أو مستوطنين. بالطبع ، يمكنك إضافتها إذا أردت. في الجوهر ، فإن المتطلب الوحيد للكيان هو أن يتم وضع تعليق توضيحي للحقل مع تعليق توضيحي org.springframework.data.annotation.Id
(ولكن على org.springframework.data.annotation.Id
، وليس javax.persistence one
).
بعد ذلك ، تحتاج إلى تحديد المستودع. أسهل طريقة للقيام بذلك هي توسيع واجهة CrudRepository
.
interface CustomerRepository extends CrudRepository<Customer, Long> {}
أخيرًا ، تحتاج إلى تكوين ApplicationContext
بحيث يتم إنشاء تطبيق هذه الواجهة تلقائيًا:
@Configuration @EnableJdbcRepositories (1) public class CustomerConfig extends JdbcConfiguration { (2) @Bean NamedParameterJdbcOperations operations() { (3) return new NamedParameterJdbcTemplate(dataSource()); } @Bean PlatformTransactionManager transactionManager() { (4) return new DataSourceTransactionManager(dataSource()); } @Bean DataSource dataSource(){ (5) return new EmbeddedDatabaseBuilder() .generateUniqueName(true) .setType(EmbeddedDatabaseType.HSQL) .addScript("create-customer-schema.sql") .build(); } }
دعونا نحلل التكوين بمزيد من التفاصيل.
EnableJdbcRepositories
إنشاء المخزون التلقائي. لكي يعمل هذا ، تحتاج إلى توفير العديد من الفاصوليا الإضافية ، والتي تتطلب بقية فئة التكوين لدينا.- لأن تمتد فئة التكوين إلى
JdbcConfiguration
، ستتم إضافة العديد من الفاصوليا إلى السياق تلقائيًا. يمكنك أيضًا تداخلها إذا كنت بحاجة إلى تغيير سلوك Spring Data JDBC. ولكن في هذا المثال ، سنترك السلوك الافتراضي. - أحد المكونات الهامة للغاية هو
NamedParameterJdbcOperations
، والذي يتم استخدامه لإجراء استعلامات قاعدة البيانات. - مدير المعاملات ، بصرامة ، غير مطلوب. ولكن بدونها ، لن يكون هناك دعم للمعاملات ، والقليل سيحبها ، أليس كذلك؟
- Spring Data JDBC لا تستخدم
DataSource
مباشرة ، لكن TransactionManager
و NamedParameterJdbcOperation
تتطلب وجودها في السياق ، ولهذا السبب نحدد الفول المطلوب.
هذا كل ما يتطلبه الأمر لبدء استخدام Spring Data JDBC. اكتب الآن اختبارًا لمعرفة كيف يعمل كل شيء:
@RunWith(SpringRunner.class) @Transactional @ContextConfiguration(classes = CustomerConfig.class) public class CustomerRepositoryTest { @Autowired CustomerRepository customerRepo; @Test public void createSimpleCustomer() { Customer customer = new Customer(); customer.dob = LocalDate.of(1904, 5, 14); customer.firstName = "Albert"; Customer saved = customerRepo.save(customer); assertThat(saved.id).isNotNull(); saved.firstName = "Hans Albert"; customerRepo.save(saved); Optional<Customer> reloaded = customerRepo.findById(saved.id); assertThat(reloaded).isNotEmpty(); assertThat(reloaded.get().firstName).isEqualTo("Hans Albert"); } }
@Query
فقط مع طرق CRUD القياسية يمكنك الذهاب بعيدًا عن مستودع فئة CrudRepository
. قررنا عمدًا تأجيل إنشاء استعلام تلقائي - وهي ميزة شائعة في Spring Data ، عندما يتم إنشاء استعلامات SQL استنادًا إلى اسم الطريقة - للإصدارات المستقبلية. وفي الوقت الحالي ، يمكنك ببساطة استخدام التعليق التوضيحي @Query
المألوف لتحديد أي استفسار SQL يجب تنفيذه بالضبط.
@Query("select id, first_name, dob from customer where upper(first_name) like '%' || upper(:name) || '%' ") List<Customer> findByName(@Param("name") String name);
إذا كنت ترغب في تعديل البيانات أو حذفها في الطلب ، يمكنك إضافة التعليق التوضيحي @Modifying
إلى الطريقة.
دعنا نكتب اختبارًا لنرى كيف تعمل طريقتنا الجديدة.
@Test public void findByName() { Customer customer = new Customer(); customer.dob = LocalDate.of(1904, 5, 14); customer.firstName = "Albert"; Customer saved = customerRepo.save(customer); assertThat(saved.id).isNotNull(); customer.id= null; (1) customer.firstName = "Bertram"; customerRepo.save(customer); customer.id= null; customer.firstName = "Beth"; customerRepo.save(customer); assertThat(customerRepo.findByName("bert")).hasSize(2); (2) }
- لأن نظرًا لأن الاتصال بين كائنات Java والسجل في قاعدة البيانات يكون فقط حسب حقل ونوع
Id
، فإن تعيين Id
على قيمة null
وحفظ هذا الكائن سيؤدي إلى إنشاء سجل جديد. - في الطلب ، نستخدم حساسة لحالة الأحرف مثل ، وبالتالي نجد "ألبرت" و "بيرترام" ، ولكن ليس "بيت".
في الختام
بالطبع ، يمكن قول الكثير عن Spring Data JDBC ، وسنخبرك بالتأكيد في المقالات المستقبلية.
في هذه الأثناء ، يمكنك دراسة نموذج التعليمات البرمجية والوثائق وبالطبع شفرة المصدر . إذا كان لديك أي أسئلة ، فلا تتردد في طرحها على StackOverflow . وإذا وجدت خطأ أو كنت تريد طلب ميزة جديدة - يرجى إنشاء تذكرة .