Вопрос

Скажем, у меня есть 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 (скажем, Blogpostid = 1). Так что эта строка будет получена и 1,3 не так, как она внутреннего соединения. Как я могу написать такого рода запрос в Jpql.?

В JPQL мы можем только написать простые запросы, как говорят:

Select bm.blogId from tblBlogMember Where bm.UserId = 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 Внутренние соединения (присоединения отношений) Спецификации:

4.4.5.1 Внутренние соединения (присоединения отношений)

Синтаксис для операции внутреннего соединения

[ 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