مقدمة إلى تعدد الأشكال مع محركات قواعد البيانات في NoSQL باستخدام Jakarta NoSQL

البوليمورفسم، مفهوم أساسي في برمجة الأجسام الواجهية، يسمح بمعاملة الأجسام من أنواع مختلفة كمثالات لفئة رئيسية مشتركة. هذه القابلية التي تمثل الأمانة الذهبية لخلق الأنظمة التي يمكن توسيعها وصيانتها بسهولة. بينما يمكن لقواعد البيانات SQL التقليدية المرتبطة مع دالة جاكارتا الاستمرارية (JPA) التعامل مع البيانات البوليمورفية، فإن قواعد البيانات NoSQL توفر ميزات مميزة. على عكس قواعد البيانات SQL التي تتطلب تعريفات المخطط الشديدة الصرامة، تأخذ قواعد البيانات NoSQL طريقة بدون مخطط، تدعم بشكل طبيعي البنية الدينامية والمرنة للبيانات. تصبح هذه القابلية مثيرة للاهتمام خاصة عندما تتم إدماجها مع جاكارتا NoSQL، أداة توفر دعم قوي لتعريف وإدارة الحقول البوليمورفية من خلال محولات مخصصة.

في العديد من التطبيقات الشركاتية، هناك حاجة شائعة لإدارة أنواع مختلفة من الأجسام البياناتية. على سبيل المثال، قد تتعامل منصة التجارة الإلكترونية بطرق مختلفة للدفع مثل البطاقات الائتمانية والمحفظات الرقمية والتحويلات البنكية، كلها تمتلك الصفات الخاصة. وبالمثل، تتعامل أنظمة إدارة الأصول في الشركات الكبيرة بأنواع مختلفة من الأصول مثل العقارات والآلات والملكية الفكرية، وكلها تمتلك خصائصها الخاصة. يتعامل أنظمة الرعاية الصحية مع أنواع مختلفة من البيانات، من المعلومات الشخصية إلى السجلات الطبية ونتائج الاختبارات. إستخدام قواعد البيانات NoSQL مع الحقول البوليمورفية يمكن تخزين وإدارة هذه الأنواع المتنوعة من البيانات بشكل متحد. تبدو أيضًا طبيعة بدون المخطط لقواعد البيانات NoSQL أسهل في التكيف مع الاحتياجات التغييرية من قواعد البيانات الرеляциونية.

هذا التورية ستريد أن يظهر كيفية استخدام Jakarta NoSQL لإدارة الحقول المتعددة الأنماطية باستخدام متحولات خاصة. سنشمل معلومات عينة للتكامل مع الخدمات الرسمية الوظيفية باستخدام Helidon و Oracle NoSQL. سيظهر هذا المثال عملية تطبيق التعددية المميزة في إدارة أنواع مختلفة من البيانات في بيئة قاعدة بيانات NoSQL بدون نمط.

إستخدام التعددية مع NoSQL و Jakarta NoSQL

سيكون هذا التورية يبحث في قابلية NoSQL والتخليص البياناتي بدون نمط في العالم الجافا باستخدام Oracle NoSQL و Java Helidon و API الرسائل. سنقوم بإنشاء كيان Machine حيث سيوفر حقل engine الذي سنحوله إلى JSON. وبسبب التواضع الطبيعي لOracle NoSQL وتصميمها البدون نمط، سيعمل هذا النهج بشكل سلس.

الخطوة الأولى هي إنشاء مشروع Helidon، حيث يمكنك استخدام Helidon Starter المبتدأ.

بعد إنشاء مشروع يتوافق مع Microprofile، فإن الخطوة التالية هي تضمين مقدم الOracle NoSQL: مقدم Oracle NoSQL.

في الملف الخصيص للمعلومات، لأننا سنقوم بالتشغيل محلياً، نحتاج إلى خصائصين: أولًا لتعريف قاعدة الاتصال وثانًا لتعريف إسم القاعدة البياناتية:

Properties files

 

jnosql.document.database=machines
jnosql.oracle.nosql.host=http://localhost:8080

أيضًا قم بتحديث المنبه لإستخدام 8181:

Properties files

 

server.port=8181

.تم تكوين وتشغيل Oracle NoSQL. للتسهيل، سنستخدم Docker، ولكن من المهم ملاحظة أن Oracle NoSQL أيضًا يدعم النشر السحابي على البنية التحتية لـ Oracle:

Shell

 

docker run -d --name oracle-instance -p 8080:8080 ghcr.io/oracle/nosql:latest-ce

باستخدام Docker، نبسط عملية الإعداد ونضمن أن مثيل Oracle NoSQL الخاص بنا يعمل في بيئة محكومة. يوفر هذا الإعداد نهجًا عمليًا لأغراض التطوير والاختبار، مع إبراز مرونة نشر Oracle NoSQL في بيئات مختلفة، بما في ذلك البنية التحتية السحابية.

بعد إعداد التكوين والقاعدة البيانات، تتضمن الخطوة التالية تعريف الكيان وإنشاء تنفيذ المحول. في هذا المثال، سنوضح التكامل السلس بين Jakarta NoSQL و Jakarta JSON-B، وكيف يمكن أن تعمل المواصفات المختلفة لـ Jakarta معًا بشكل فعال.

الخطوة الأولية هي تعريف كيان الآلة، والذي يتضمن حقل محرك متعدد الأشكال.

Java

 


@Entity
@JsonbVisibility(FieldAccessStrategy.class)
public class Machine {

    @Id
    private String id;

    @Column
    @Convert(EngineConverter.class)
    private Engine engine;

    @Column
    private String manufacturer;

    @Column
    private int year;

    // الوصول والتعيين
}

بعد ذلك، نحدد فئة المحرك، مع تحديد الأنواع والتنفيذات باستخدام JsonbTypeInfo لمعالجة التعدد الشكلي:

Java

 

@JsonbTypeInfo(
        key = "type",
        value = {
                @JsonbSubtype(alias = "gas", type = GasEngine.class),
                @JsonbSubtype(alias = "electric", type = ElectricEngine.class)
        }
)
@JsonbVisibility(FieldAccessStrategy.class)
public abstract class Engine {
    // سمات المحرك المشتركة

    // الوصول والتعيين
}

قد يختلف محول المحرك حسب المزود؛ يمكن أن يعمل كـ String أو Map أو BSON وما إلى ذلك.

بعد إعداد التكوين وقاعدة البيانات، الخطوة التالية هي إنشاء جسر التطبيق وقاعدة البيانات. يدمج Eclipse JNoSQL مواصفتين، Jakarta NoSQL و Jakarta Data، باستخدام واجهة واحدة لتحقيق ذلك. تتعامل التعليمات الإرشادية مع الخطوات الضرورية.

أولاً، نعرّف واجهة MachineRepository:

Java

 

@Repository
public interface MachineRepository extends BasicRepository<Machine, String> {

    @Query("from Machine where engine.type = :type")
    List<Machine> findByType(@Param("type") String type);
}

تسمح لنا هذه واجهة المستودع بالبحث عن العناصر مباشرة داخل بيانات JSON دون أي مشاكل، ويمكنك توسيعها بشكل أكبر دون إنشاء هيكل صارم.

بعد ذلك، نعرّف وحدة التحكم لعرض هذا المورد:

Java

 


@Path("/machines")
@ApplicationScoped
public class MachineResource {

    private static final Logger LOGGER = Logger.getLogger(MachineResource.class.getName());

    public static final Order<Machine> ORDER_MANUFACTURER = Order.by(Sort.asc("manufacturer"));

    private final MachineRepository repository;

    @Inject
    public MachineResource(@Database(DatabaseType.DOCUMENT) MachineRepository repository) {
        this.repository = repository;
    }

    @GET
    public List<Machine> getMachines(@QueryParam("page") @DefaultValue("1") int page, @QueryParam("page_size") @DefaultValue("10") int pageSize) {
        LOGGER.info("Get machines from page " + page + " with page size " + pageSize);
        Page<Machine> machines = this.repository.findAll(PageRequest.ofPage(page).size(pageSize), ORDER_MANUFACTURER);
        return machines.content();
    }

    @GET
    @Path("gas")
    public List<Machine> getGasMachines() {
        return this.repository.findByType("gas");
    }

    @GET
    @Path("electric")
    public List<Machine> getElectricMachines() {
        return this.repository.findByType("electric");
    }

    @GET
    @Path("{id}")
    public Machine get(@PathParam("id") String id) {
        LOGGER.info("Get machine by id " + id);
        return this.repository.findById(id)
                .orElseThrow(() -> new WebApplicationException("Machine not found with id: " + id, Response.Status.NOT_FOUND));
    }

    @PUT
    public void save(Machine machine) {
        LOGGER.info("Saving a machine " + machine);
        this.repository.save(machine);
    }
}

توفر هذه وحدة التحكم نقاط نهائية لإدارة الآلات، بما في ذلك الحصول على الآلات حسب النوع والتقسيم إلى صفحات.

أخيرًا، قم بتنفيذ التطبيق وإدراج البيانات باستخدام أوامر curl التالية:

Shell

 

curl --location --request PUT 'http://localhost:8181/machines' \
--header 'Content-Type: application/json' \
--data '{
"id": "1",
"model": "Thunderbolt V8",
"engine": {
"type": "gas",
"horsepower": 450
},
"manufacturer": "Mustang",
"year": 2021,
"weight": 1600.0
}'

curl --location --request PUT 'http://localhost:8181/machines' \
--header 'Content-Type: application/json' \
--data '{
    "id": "2",
    "model": "Eagle Eye EV",
    "engine": {
        "type": "electric",
        "horsepower": 300
    },
    "manufacturer": "Tesla",
    "year": 2022,
    "weight": 1400.0
}'

curl --location --request PUT 'http://localhost:8181/machines' \
--header 'Content-Type: application/json' \
--data '{
    "id": "3",
    "model": "Road Runner GT",
    "engine": {
        "type": "gas",
        "horsepower": 400
    },
    "manufacturer": "Chevrolet",
    "year": 2020,
    "weight": 1700.0
}'

curl --location --request PUT 'http://localhost:8181/machines' \
--header 'Content-Type: application/json' \
--data '{
    "id": "4",
    "model": "Solaris X",
    "engine": {
        "type": "electric",
        "horsepower": 350
    },
    "manufacturer": "Nissan",
    "year": 2023,
    "weight": 1350.0
}'

curl --location --request PUT 'http://localhost:8181/machines' \
--header 'Content-Type: application/json' \
--data '{
    "id": "5",
    "model": "Fusion Hybrid 2024",
    "engine": {
        "type": "electric",
        "horsepower": 320
    },
    "manufacturer": "Toyota",
    "year": 2024,
    "weight": 1450.0
}'

يسمح لك هذا الإعداد بالبحث حسب النوع داخل JSON، ويمكن تنفيذ التقسيم إلى صفحات بسهولة. لمزيد من المعلومات حول تقنيات التقسيم إلى صفحات، راجع هذا المقال.

بعد إدراج بعض البيانات، يمكنك استكشاف وفهم كيفية عمل البحث:

  • الحصول على الآلات باستخدام التصفيح
  • الحصول على جميع الآلات
  • الحصول على آلات الغاز

أفكار ختامية

إن دمج البوليمورفية مع قواعد البيانات NoSQL باستخدام Jakarta NoSQL و Jakarta JSON-B يوفر المرونة والكفاءة في إدارة أنواع البيانات المختلفة. من خلال الاستفادة من طبيعة عدم وجود نظام للبيانات في NoSQL، يبسط هذا النهج التطوير ويعزز قابلية تكيف التطبيق. للحصول على المثال الكامل وشفرة المصدر، قم بزيارة soujava/helidon-oracle-json-types.

Source:
https://dzone.com/articles/intro-to-polymorphism-with-db-engines-in-nosql