我有一个用户和一个消息表。 User to Message是一对多关系,Message to User是多对一关系。我已将多对一中的一个标记为fetch join。当我得到一条消息时,Hibernate会运行一个连接查询,但是当我获取所有消息时,Hibernate会运行select查询而不是连接。可能是什么原因?以下是详细信息:
他们之间的关系:
用户
<set name="messagesForFromUserUid" lazy="true" table="message" inverse="true" cascade="save-update">
<key>
<column name="from_user_uid" not-null="true" />
</key>
<one-to-many class="repository.Message" />
</set>
<set name="messagesForToUserUid" lazy="true" table="message" fetch="select">
<key>
<column name="to_user_uid" not-null="true" />
</key>
<one-to-many class="repository.Message" />
</set>
消息
<many-to-one name="userByFromUserUid" class="repository.User" fetch="join" lazy="false">
<column name="from_user_uid" not-null="true" />
</many-to-one>
<many-to-one name="userByToUserUid" class="repository.User" fetch="select" lazy="proxy">
<column name="to_user_uid" not-null="true" />
</many-to-one>
当我获取单个消息对象时,Hibernate按预期运行一个连接查询:
Message m = (Message) s.get(Message.class, 2);
Hibernate:
select
message0_.message_uid as message1_1_1_,
message0_.from_user_uid as from2_1_1_,
message0_.to_user_uid as to3_1_1_,
message0_.message_text as message4_1_1_,
message0_.created_dt as created5_1_1_,
user1_.user_uid as user1_0_0_,
user1_.user_name as user2_0_0_,
user1_.user_password as user3_0_0_,
user1_.email as email0_0_,
user1_.first_name as first5_0_0_,
user1_.last_name as last6_0_0_,
user1_.created_dt as created7_0_0_
from
hello.message message0_
inner join
hello.user user1_
on message0_.from_user_uid=user1_.user_uid
where
message0_.message_uid=?
但是,当我一次性获取所有消息时,Hibernate会运行选择查询:
List<Message> l = s.createQuery("from Message").list();
Hibernate:
select
message0_.message_uid as message1_1_,
message0_.from_user_uid as from2_1_,
message0_.to_user_uid as to3_1_,
message0_.message_text as message4_1_,
message0_.created_dt as created5_1_
from
hello.message message0_
Hibernate:
select
user0_.user_uid as user1_0_0_,
user0_.user_name as user2_0_0_,
user0_.user_password as user3_0_0_,
user0_.email as email0_0_,
user0_.first_name as first5_0_0_,
user0_.last_name as last6_0_0_,
user0_.created_dt as created7_0_0_
from
hello.user user0_
where
user0_.user_uid=?
Hibernate:
select
user0_.user_uid as user1_0_0_,
user0_.user_name as user2_0_0_,
user0_.user_password as user3_0_0_,
user0_.email as email0_0_,
user0_.first_name as first5_0_0_,
user0_.last_name as last6_0_0_,
user0_.created_dt as created7_0_0_
from
hello.user user0_
where
user0_.user_uid=?
答案 0 :(得分:2)
对于HQL或Criteria查询,Hibernate看起来并不总是使用映射中定义的获取策略。它们通常用于获取/加载。在此处找到了参考:https://forum.hibernate.org/viewtopic.php?f=1&t=957561
答案 1 :(得分:0)
我不确定但这可能是原因。如果运行单个查询,即连接或子查询。没关系,单个查询可能没有任何性能差异。但是,如果您正在运行多个查询(在您的情况下是多个消息),可能会引发性能问题。我肯定会选择简单的选择查询而不是连接/子查询。如果我们考虑性能,这肯定是有道理的。这就是Hibernate所做的。