سؤال

في جداول قاعدة البيانات القديمة لدينا أعمدة مرقمة مثل C1، C2، C3، C100 أو M1، M2، M3، M100.
تمثل هذه الأعمدة بيانات Blob.

لا يمكن تغيير أي شيء له قاعدة البيانات هذه.

باستخدام JPA AMBEDDABLE نحن خريطة جميع الأعمدة إلى الحقول الفردية. ثم أثناء التضمين، نتجاوز الأسماء باستخدام التعليقات التوضيحية 100 تجاوز.

في الآونة الأخيرة لقد تحولنا إلى السبات ووجدت أشياء مثل Usercoclectionpe. و compositeusertype.. وبعد لكنني لم أجد أي حالات استخدام قريبة من الألغام.

هل من الممكن تنفيذ بعض نوع المستخدم باستخدام السبات لتكون قادرا على تعيين حزمة من الأعمدة إلى مجموعة دون استعلام إضافي?

يحرر:
كما لاحظت ربما يمكن أن تختلف أسماء الأعمدة عن الجدول إلى جدول. أريد إنشاء نوع واحد مثل "LEGACYArray" دون حاجة لتحديد كافة olumns كل مرة في كل مرة استخدم فيها هذا النوع. ولكن بدلا من ذلك كنت أستخدم

  @Type(type = "LegacyArrayUserType",
        parameters =
   {
      @Parameter(name = "prefix", value = "A"),
      @Parameter(name = "size", value = "128")
   })
   List<Integer> legacyA;

  @Type(type = "LegacyArrayUserType",
        parameters =
   {
      @Parameter(name = "prefix", value = "B"),
      @Parameter(name = "size", value = "64")
   })
   List<Integer> legacyB;
هل كانت مفيدة؟

المحلول

أستطيع أن أفكر في بضعة طرق لأفعل ذلك.

1. قم بإنشاء طرق عرض معلومات المجموعة التي تحاكي بنية جدول طبيعية، وتعريضها على السبات كجهاز جمع:

على افتراض أن جدولك الحالي يسمى primaryentity, ، أود أن أخلق طريقة مشابهة لما يلي:

-- untested SQL...
create view childentity as
(select primaryentity_id, c1 from primaryentity union
select primaryentity_id, c2 from primaryentity union
select primaryentity_id, c3 from primaryentity union
--...
select primaryentity_id, c100 from primaryentity)

الآن من وجهة نظر السبات، childentity هو مجرد طاولة طبيعية لها مفتاح أجنبي primarykey. وبعد تعيين هذا يجب أن يكون مستقيما جدا إلى الأمام، ومغطاة هنا:

فوائد هذا النهج:

  • من وجهة نظر الإسبات، يتم تطبيع الجداول، إنها رسم خرائط بسيطة إلى حد ما
  • لا توجد تحديثات للجداول الحالية

العيوب:

  • البيانات للقراءة فقط، لا أعتقد أن عرضك يمكن تعريفه بطريقة قابلة للتحديث (قد أكون مخطئا)
  • يتطلب التغيير في قاعدة البيانات، قد تحتاج إلى إنشاء الكثير من وجهات النظر

بالتناوب، إذا لن يسمح لك DBA بإضافة وجهة نظر إلى قاعدة البيانات، أو إذا كنت بحاجة إلى إجراء التحديثات:


2. استخدام السبات مرفق رسم الخرائط نموذج ديناميكي لتعيين خصائص C1، C2، C3 خريطة, ، ولدي بعض الكود لك داو طبقة تفعل المحادثة المناسبة بين الخريطة وخاصية المجموعة:

لم أفعل هذا بنفسي، لكنني أعتقد أن السبات يتيح لك تعيين الجداول إلى الحاشات. لست متأكدا من مدى تسمح لك السبات ديناميكيا بالقيام بذلك (أي، هل يمكنك الابتعاد ببساطة تحديد اسم الجدول، وتوجيه السبات تلقائيا جميع الأعمدة؟)، لكنها طريقة أخرى يمكنني التفكير في القيام بذلك.

إذا كان الذهاب مع هذا النهج، تأكد من استخدام كائن الوصول إلى البيانات نمط، والتأكد من إخفاء التنفيذ الداخلي (استخدام Hashmaps) من رمز العميل. تأكد أيضا من التحقق قبل الكتابة إلى قاعدة البيانات التي لا تتجاوز حجم مجموعتك عدد الأعمدة المتاحة.

فوائد هذا النهج:

  • لا تغيير في قاعدة البيانات على الإطلاق
  • البيانات قابلة للتحديث
  • س / ص خرائط بسيطة نسبيا

العيوب:

  • الكثير من السباكة في طبقة DAO لتعيين الأنواع المناسبة
  • يستخدم ميزات السبات التجريبية التي قد تتغير في المستقبل

نصائح أخرى

شخصيا، أعتقد أن التصميم يبدو وكأنه يكسر أول نموذج طبيعي لقواعد البيانات العلائقية. ماذا يحدث إذا كنت بحاجة إلى C101 أو M101؟ تغيير المخطط الخاص بك مرة أخرى؟ أعتقد أنها تدخلي للغاية.

إذا قمت بإضافة السبات إلى المزيج، فمن الأسوأ. إضافة C101 أو M101 تعني الاضطرار إلى تغيير كائنات Java الخاصة بك، وتعيينات السبات الخاصة بك، كل شيء.

إذا كان لديك 1: M العلاقات مع جداول C و M، فستكون قادرا على التعامل مع الحالات التي استشهد بها للتو عن طريق إضافة صفوف إضافية. كائنات Java الخاصة بك تحتوي على مجموعةu003CC> أو جمعu003CM> وبعد تعينات السبات الخاصة بك هي واحدة لا تتغير.

ربما السبب في أنك لا ترى أي أمثلة رائعة لتتناسب مع قضيتك لأنه تصميم غير مستحسن.

إذا كان يجب، ربما يجب أن ننظر إلى تعيين مظلة السبات.

تحديث: حقيقة أن هذا هو إرث يبدو حسب الأصول. وجهة نظري في إحضار النموذج العادي الأول هو بالنسبة للآخرين الذين قد يجدون هذا السؤال في المستقبل كما هو الحال بالنسبة للشخص الذي نشر السؤال. لا أريد الإجابة على السؤال بطريقة تؤكد هذا التصميم بصمت بأنه "جيد".

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

آسف إذا كنت أسيء فهم مشكلتك هنا، وأنا لا أعرف الكثير عن السبات. ولكن لم أستطع فقط التسلسل أثناء الاختيار من قاعدة البيانات للحصول على شيء مثل ما تريد؟

يحب:

SELECT whatever
     , C1||C2||C3||C4||...||C100 AS CDATA
     , M1||M2||M3||M4||...||M100 AS MDATA
FROM ...
WHERE ...

(بالطبع، يختلف مشغل التسلسل بين RDBMSs.)

تحرير] أقترح استخدام CompositeUserType. هنا مثال. وبعد هناك أيضا مثال جيد في صفحة 228F في كتاب "Java Distribence with Libernate".

يتيح لك ذلك التعامل مع الأعمدة العديدة ككائن واحد في Java.

الرشى يبدو وكأنه هذا:

@org.hibernate.annotations.Columns(columns = {
    @Column(name="C1"),
    @Column(name="C2"),
    @Column(name="C3"),
    ...
})
private List<Integer> c;

سوف تحميل السبات جميع الأعمدة في وقت واحد أثناء الاستعلام العادي.

في حالتك، يجب عليك نسخ قيم INT من القائمة إلى عدد ثابت من الأعمدة في nullSafeSet. وبعد كود مزيف:

for (int i=1; i<numColumns; i++)
    if (i < list.size())
        resultSet.setInt(index+i, list.get(i));
    else
        resultSet.setNull(index+i, Hibernate.INTEGER.sqlType());

في nullSafeGet يجب عليك إنشاء قائمة وتوقف عن إضافة عناصر عند وجود عمود فارغ. للحصول على سلامة إضافية، أقترح إنشاء تطبيق القائمة الخاصة بك والتي لا تسمح بالنمو وراء عدد الأعمدة (ورث ArrayList وتجاوز ensureCapacity()).

edit2] إذا كنت لا ترغب في كتابة جميع التعليقات التوضيحية Columums، فاستخدم مولد التعليمات البرمجية لهم. يمكن أن يكون هذا بسيطا مثل البرنامج النصي الذي تعطيه اسم ورقم وطباعة Column (...) إلى System.out. بعد ركض البرنامج النصي، فقط قص واللصق البيانات في المصدر.

سيكون الحل الآخر الوحيد هو الوصول إلى واجهة برمجة تطبيقات السبات الداخلية لبناء هذه المعلومات في وقت التشغيل ولكن أن واجهة برمجة التطبيقات الداخلية داخلية، لذلك الكثير من الأشياء خاصة. يمكنك استخدام انعكاس جافا و setAccessible(true) ولكن هذا الرمز ربما لن ينجو من التحديث التالي للعائلة.

يمكنك استخدام UserTypeS لتعيين عدد معين من الأعمدة إلى أي نوع تريده. قد يكون هذا مجموعة إذا كان (على سبيل المثال) للمجموعات دائما يحدها دائما من قبل عدد معروف من العناصر.

لقد كان بعض الوقت (> 3 سنوات) منذ أن استخدمت السبات، لذلك أنا صدئ جدا لكنني أتذكر أنه من السهل جدا القيام به؛ لك BespokeUserType يتم تمرير الفصل ResultSet ل هيدرات كائنك منه.

أنا أيضا لم تستخدم السبات أبدا.

أقترح كتابة برنامج صغير في لغة تفسير (مثل بيثون) يمكنك من خلالها تنفيذ سلسلة كما لو كانت أمر. يمكنك إنشاء بيان يأخذ العمل الشامل من فعل ما تريد القيام به يدويا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top