【问题标题】:How to use Hibernate eqOrIsNull()如何使用休眠 eqOrIsNull()
【发布时间】:2013-10-19 21:30:31
【问题描述】:

我在 MySQL 中有两行这样的

+---------+---------+
| foo     | bar     |
+---------+---------+
|         | NULL    |
|         |         |
+---------+---------+

其中空是空字符串""

现在我想同时获得它们。我在两列上都使用了CriteriaRestrictions.eqOrIsNull(),但它总是只返回一行。

代码是这样的

criteria.add(Restrictions.eqOrIsNull("foo", ""));
        .add(Restrictions.eqOrIsNull("bar", ""));

当我仅在foo 上添加条件时,它会返回两行。但是对于bar,它只返回第二个,它是空的。

javadoc 说,Apply an "equal" constraint to the named property. If the value is null, instead apply "is null". 那么是我弄错了,还是应该以其他方式使用它?

更新
对不起,我太粗心了。文档清楚地说明了这一点。此方法根据传递给它的value 工作,而不是存储在 DB 中的命名属性的实际值。
Github上的源码:

public static Criterion eqOrIsNull(String propertyName, Object value) {
    return value == null
            ? isNull( propertyName )
            : eq( propertyName, value );
}

所以在我的例子中,eqOrIsNull 返回eq("")。我应该使用 eqisNull 的析取,比如 Gregory answered

【问题讨论】:

  • 对于此类问题,您应该启用调试日志记录。它会让hibernate打印正在执行的sql。
  • 有点像select foo,bar from table where foo=? and bar=?

标签: java mysql hibernate


【解决方案1】:

对命名属性应用“相等”约束。如果值为 null,而是应用“is null”。

这意味着,is null 将仅在 NULL 作为值传递时应用。 如果您指定任何其他字符串作为值,则只会应用equal

当您不确定在运行时作为参数传递给参数值的实际值时,这很有用。 在这种情况下,以传统方式,您需要放置一个不为空检查并根据不为空条件编写条件,或者您需要按照 Gregory 的回答中提到的方式编写条件。

牢记所有这些事实,您应该得到问题的答案。 你只得到那些包含空值的行而不是那些具有 NULL 值的行,因为你已经指定了一个空字符串作为第二个参数。如果您将 NULL 指定为第二个参数,您将只获得那些具有 NULL 值的行。

如果这对你有帮助,请告诉我。

【讨论】:

  • 感谢您的解释。我已经阅读了文档和源代码,发现了我的问题。查看我的更新。
【解决方案2】:

检查此代码是否符合您的要求 -

criteria.add(Restrictions.or(Restrictions.eq("foo", ""), Restrictions.isNull("foo")))
                .add(Restrictions.or(Restrictions.eq("bar", ""), Restrictions.isNull("bar")));

这个 sn-p 使用 Hibernate 3.5.0-CR-2 API。

【讨论】:

  • 在这种情况下它可以工作,但如果一列有非空内容,它也会得到。
  • 这个有效...您能解释一下为什么这与eqOrIsNull() 不同吗?我正在使用休眠 4.2.5。
【解决方案3】:

是的,如果以前从未使用过,这是非常模棱两可的,从 ORM 抽象的角度来看,区分 eq null 或 is null 完全没有意义。那是遗留的 SQL 思维。

我最初还认为它是or(eq("foo"), isNull("foo")) 的快捷方式,因为我在eq 始终像eqOrIsNull 一样工作的条件下有自己的过滤层。

强文本

/**
 * Checks if the given property is <code>null</code> or equals the given
 * value. If the given value is <code>null</code> it is only checked for
 * being <code>null</code>.
 *
 * @param property Property name
 * @param value Value to check against
 *
 * @return Disjunction
 */
public static Criterion isValueEqOrNull(final String property, final Object value)
{
    Objects.requireNonNull(property, "property must not be null");

    if (value == null)
        return Restrictions.isNull(property);
    else
        return Restrictions.or(Restrictions.eq(property, value), Restrictions.isNull(property));
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-08
    • 1970-01-01
    • 2015-11-07
    • 2014-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多