Скажите, что у меня есть 5 таблиц,
tblBlogs tblBlogPosts tblBlogPostComment tblUser tblBlogMember
BlogId BlogPostsId BlogPostCommentId UserId BlogMemberId
BlogTitle BlogId CommentText FirstName UserId
PostTitle BlogPostsId BlogId
BlogMemberId
Теперь я хочу получить только те блоги и сообщения, для которых на самом деле прокомментировал blogMember. Таким образом короче говоря, как я пишу этот простой 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;
Где objUser предоставляется с помощью:
em.find(User.class,1);
Таким образом, после того как мы добираемся, все блоги (здесь blogId представляет объект блога), какой пользователь присоединился, мы можем циклично выполниться через и действительно все представляем себе вещи. Но я не хочу падать в этом бизнесе цикличного выполнения и писать всему этому вещи в моем коде Java. Вместо этого я хочу оставить это, чтобы механизм базы данных сделал. Так, как я пишу вышеупомянутой плоскости SQL в JPQL? И какой объект JPQL запросит возврат? Поскольку я только выбираю немного полей из всей таблицы. В котором классе я должен преобразовать тип результата к?
Я думаю, что отправил свое требование правильно, если я не ясен сообщенный мне.
ОБНОВЛЕНИЕ: Согласно ответу Паскаля, я пытался записать запрос 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
Вышеупомянутый запрос не работает. Как я могу решить эту проблему?
Хорошо, это окончательный ответ. На создание этой единственной линии ушел один час. За этот час у меня было много странных ошибок, но теперь мои концепции достаточно ясны:
@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
Ключевое слово INNER может быть дополнительно использовать:
SELECT c FROM Customer c INNER JOIN c.orders o WHERE c.status = 1
Вам просто нужно подумать об ассоциации между сущностями.