如何在Hibernate中向Criteria API添加限制

时间:2012-12-10 09:18:00

标签: spring hibernate java-ee hibernate-mapping hibernate-criteria

我是Hibernate和Spring的新手。我的问题是关于“如何添加标准......”的情况,例如,我有两个豆子:

1)语言:

public class Language {
    private int languageId;
    private String languageName;
    private List<Topic> listOfAllTopics;
}

2)主题:

public class Topic {
    private int topicId;
    private String topicName;
}

我的数据库表:

1)语言

language_id       int(PK)
language_name     varchar(30)

2)主题

topic_id          int(PK)
topic_name        varchar(30)
language_id       int(FK)

Hibernate映射xml文件是:

1)Language.hbm.xml

<hibernate-mapping package="com.mw.javamentordb.dto">
    <class name="Language" table="language" lazy="true">
        <id name="languageId" column="language_id" type="int">
            <generator class="increment" />
        </id>
        <property name="languageName" column="language_name"type="string"/>
        <bag name="listOfAllTopics" cascade="all">
        <key column="language_id" not-null="true" />
        <one-to-many class="Topic"/>
        </bag>
    </class>
</hibernate-mapping>

2)Topic.hbm.xml

<hibernate-mapping package="com.mw.javamentordb.dto">
    <class name="Topic" table="topics" lazy="true">
        <id name="topicId" column="topics_id" type="int">
            <generator class="increment" />
        </id>
        <property name="topicName" column="topics_name" type="string" />
    </class>
</hibernate-mapping>

我使用这种方法在我的数据库中获得所有语言,并且它可以正常工作。

public List<Language> getAllLanguages() {
    Criteria criteria = getSession().createCriteria(Language.class);
    return criteria.list();
}

但是当我尝试使用标准获取特定语言的所有主题(通过langId)时,它不起作用。 实际上我不知道如何在这种情况下使用标准。

public List<Topic> getAllTopicOfLanguage(Language language) {
    Criteria criteria = getSession().createCriteria(Topic.class);
    criteria.add(Restrictions.eq("?");
    return criteria.list();
}

2 个答案:

答案 0 :(得分:1)

Topic的表格有一个外键约束language_id,但你的类和hbm.xml映射没有。

因此无法获得所需的查询。

将其更改为:

public class Topic 
{
    private int topicId;
    private String topicName;
    private Language language;
}

在属性hbm.xml:

<many-to-one name="language" class="package.Language" fetch="select">
    <column name="language_id">
</many-to-one>

然后您可以使用以下条件查询它:

criteria.add(Expression.eq("language.language_id", language.getLanguageId()));

或者,您可以使用对象本身的相等性来代替其ID,或使用Expression.eqId(Object Object)

建议:

使用带有标识符字段的抽象超类来使事物更通用。在类topicIdTopic和类languageId上的Language命名标识符只是开销。只需在属性,类和表上使用id即可。 在较大的应用程序中,这将变得更加明显。

答案 1 :(得分:0)

您正在通过错误的方式搜索结果,根据您的设计,您将获得结果,

public Language getAllTopicOfLanguage(Language language) {
    Criteria criteria = getSession().createCriteria(Language.class);
    criteria.add(Expression.eq("languageId",language.getLanguageId()));
    return (Language)(criteria.list().get(0));
}

这将返回语言DTO对象,其中包含仅在语言DTO中填写的与语言ID匹配的主题列表。

因为你是新手,只想告诉你,当你使用休眠时,你的DTO和桌面设计应该非常精确。