سؤال

قل لدي 5 طاولات ،

tblBlogs     tblBlogPosts     tblBlogPostComment    tblUser    tblBlogMember
BlogId        BlogPostsId       BlogPostCommentId   UserId      BlogMemberId
BlogTitle     BlogId            CommentText         FirstName   UserId
              PostTitle         BlogPostsId                     BlogId
                                 BlogMemberId

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

SELECT b.BlogTitle, bp.PostTitle, bpc.CommentText FROM tblBlogs b 
INNER JOIN tblBlogPosts bp on b.BlogId = bp.BlogId 
INNER JOIN tblBlogPostComment bpc on bp.BlogPostsId = bpc.BlogPostsId 
INNER JOIN  tblBlogMember bm ON bpc.BlogMemberId = bm.BlogMemberId 
WHERE bm.UserId = 1;

كما ترون ، كل شيء يتمتع بالانضمام الداخلي ، لذلك سيتم استرداد هذا الصف فقط الذي علق عليه المستخدم على بعض المدونات. لذلك ، لنفترض أنه/لقد انضمت إلى 3 مدونات لها معرفاتها 1،2،3 (المدونات التي انضم إليها المستخدم في TblBlogMembers) ولكن المستخدم قد علق فقط في المدونة 2 (من say blogpostid = 1). بحيث يتم استرداد هذا الصف و 1،3 لن يكون كما هو انضمام داخلي. كيف أكتب هذا النوع من الاستعلام في JPQL?

في JPQL ، يمكننا فقط كتابة استفسارات بسيطة مثل القول:

Select bm.blogId from tblBlogMember Where bm.UserId = objUser;

حيث يتم تزويد Objuser باستخدام:

em.find(User.class,1);

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

أعتقد أنني نشرت متطلباتي بشكل صحيح ، إذا لم أكن واضحًا ، فيرجى إبلاغي بذلك.

تحديث: وفقًا لإجابة Pascal ، حاولت كتابة استعلام JPQL لاستعلام SQL أعلاه. أنا أواجه مشكلة صغيرة. هذا الاستعلام يعمل ، لكنه غير مكتمل:

SELECT bm.blogId FROM BlogMembers bm 
    INNER JOIN bm.blogId b 
    INNER JOIN b.blogPostsList bp 
    INNER JOIN bp.blogPostCommentList bpc 
    WHERE bm.userId = :userId

أريد تعديل هذا إلى:

SELECT bm.blogId FROM BlogMembers bm 
    INNER JOIN bm.blogId b 
    INNER JOIN b.blogPostsList bp 
    INNER JOIN bp.blogPostCommentList bpc 
    WHERE bpc.blogMembersId = bm.blogMembersId AND bm.userId = :userId

الاستعلام أعلاه لا يعمل. كيف يمكنني حل هذه المشكلة؟

هل كانت مفيدة؟

المحلول 2

حسنًا ، هذا هو الجواب النهائي. استغرق الأمر ساعة واحدة لتأطير هذا السطر الواحد. حصلت على العديد من الأخطاء الغريبة خلال هذه الساعة ، لكن مفاهيمي الآن واضحة بما يكفي:

@NamedQuery(name = "BlogMembers.findBlogsOnWhichCommentsAreMade", 
    query = "SELECT bm.blogId FROM BlogMembers bm INNER JOIN bm.blogId b 
    INNER JOIN b.blogPostsList bp INNER JOIN bp.blogPostCommentList bpc 
    INNER JOIN bpc.blogMembersId bmt WHERE bm.userId = :userId")

نصائح أخرى

في JPQL ، يمكننا فقط كتابة استفسارات بسيطة (...)

هذا ليس صحيحًا و JPQL يدعم [ LEFT [OUTER] | INNER ] JOIN. للوصول الداخلي ، راجع القسم 4.4.5.1 inner inner (تنضم العلاقة) من المواصفات:

4.4.5.1 inner inner (تنضم العلاقة)

بناء الجملة لعملية الانضمام الداخلية

[ INNER ] JOIN join_association_path_expression [AS] identification_variable

على سبيل المثال ، ينضم الاستعلام أدناه إلى العلاقة بين العملاء والأوامر. هذا النوع من الصلة يعادل عادةً الانضمام إلى علاقة مفتاح خارجي في قاعدة البيانات.

SELECT c FROM Customer c JOIN c.orders o WHERE c.status = 1

قد يتم استخدام الكلمة الرئيسية الداخلية اختياريًا:

SELECT c FROM Customer c INNER JOIN c.orders o WHERE c.status = 1

تحتاج فقط إلى التفكير في الارتباط بين الكيانات.

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