大家。我使用Hibernate是全新的。
所以我在这里面对一个问题,我有一个如下的实体:
<class name="cn.edu.scau.librarica.dao.MessageSession" table="msg_session">
<id name="msid" type="long" unsaved-value="null">
<generator class="identity"/>
</id>
<list name="msgs" cascade="all">
<key column="msid"
update="false" unique="true" not-null="true"/>
<list-index column="list_index"/>
<one-to-many class="Message" />
</list>
</class>
现在我想要实现的是:
select Message m where msid=# and m.t<## and m.t>###
我如何用Criteria代表它?
提前感谢您的关注和建议。
更新
作为答案指南之一,我已经明白复合元素是不可查询的,所以我做了一个两个一对多的地图(更改在上面)
现在我可以查询,但现在我发现了另一个问题:
如何使用外键来映射复合ID
Message
就是这样的地图:
<class name="Message">
<composite-id>
<generator class="foreign">
<!-- What here??? -->
</generator>
</composite-id>
</class>
根据指示,一对多可能会使用set
而不是list
,因此我很难找到符合我需要的样本(因为应该订购消息)。
有什么建议?我还在寻找那个。
谢谢你的帮助。
答案 0 :(得分:1)
您不能直接选择消息,因为它是组件而不是实体。组件没有独立的生命周期。它们不能单独查询,创建或删除,它们总是必须通过嵌入它们的实体进行访问(在您的情况下为MessageSession)。
要使其成为实体,表应具有自己的主键。在你的情况下,似乎并非如此。您将需要更改架构,以便与Message对应的表具有主键,并将映射更改为使用一对多而不是复合元素。
如果你不能这样做,你将不得不查询MessageSession并从中获取消息。
P.S:Hibernate非常复杂,我没有看到太多人只是在试图解决问题时就把它拿起来。如果你花一些时间研究基础概念(比仅仅映射和查询更重要),你更有可能成功。答案 1 :(得分:0)
这是问题的作者。
经过几天的研究,我找到了以某种方式满足我的要求的方法。
映射Message
<class name="cn.edu.scau.librarica.dao.Message" table="message">
<id name="id" type="long">
<generator class="identity" />
</id>
<many-to-one name="ms" class="cn.edu.scau.librarica.dao.MessageSession"
column="msid" not-null="true" insert="false" update="false" />
<property name="s" type="long" />
<property name="t" type="timestamp" />
<property name="m" type="string" />
</class>
映射MessageSession
<class name="cn.edu.scau.librarica.dao.MessageSession" table="msg_session">
<id name="msid" type="long" unsaved-value="null">
<generator class="identity"/>
</id>
<property name="latest" type="timestamp" />
<list name="msgs" table="msg_session_msgs" cascade="all">
<key column="msid"
update="false" not-null="true"/>
<list-index column="list_index"/>
<one-to-many class="cn.edu.scau.librarica.dao.Message" />
</list>
</class>
其中,不重要的是被忽视了。
事情进展顺利,而我可以找到限制为“很多”或相反的“一”。就像这样:
DetachedCriteria dc = DetachedCriteria.forClass(Message.class)
.createCriteria("ms")
.add(Restrictions.eq("msid", msid));
if (after != null)
dc.add(Restrictions.gt("t", after));
if (before != null)
dc.add(Restrictions.lt("t", before));
...可以在指定期间内从指定的Message
搜索MessageSession
。
所以诀窍是对象不能被Criteria返回,除非将它们作为实体匹配。
在底层数据库中,它会有点多余,因为Message
可以由(msid,list_index)
唯一标识,所以我找到了一种方法来匹配&lt; -this作为{的主键{1}}。