繁体   English   中英

如何处理JPA命名查询中数字类型的空值

[英]How to handle null value of number type in JPA named query

我想将两个参数传递给namedquery。 一种是数字类型,另一种是字符串类型。 他们都可以为空。

例如,(id=null, username='joe') 和 (id=1, username='joe') 是两个不同的结果。 在 namedQuery 中,如果 id 为 null,则语法为“u.id is null”,如果 id 不为 null,则语法为“u.id = :id”。 我的问题是如何动态处理namedQuery中提交的id?

请检查我的示例代码:

1.用户.java

@NamedQueries({
        @NamedQuery(name = "getUser", query = "select u from User u"
                + " where u.id = :id"    
                + " And u.username= :username")
})
public class User{
     public Long id;
     public String username;
}
  1. 用户道
public User getUser(Long id, String username) {
    TypedQuery<User> query = Dao.entityManager.createNamedQuery("getUser", User.class);
    query.setParameter("id", id);
    query.setParameter("username", username);

    List<User> users = query.getResultList();

    if (users.size() > 0) {
        return users.get(0);
    } else {
        return null;
    }
}

========================================

我尝试过的:

  1. 这是遗留代码,我不想更改结构。 所以我不想使用 Criteria。

  2. select u from User u where (:id is null or u.id= :id) and u.username= :username

    // 抛出异常:不一致的数据类型:预期 NUMBER 得到 BINARY

  3. select u from User u where u.id= nullif(:id, null) and u.username= :username

    // 抛出异常:不一致的数据类型:预期 NUMBER 得到 BINARY

  4. 我也在namedQuery中尝试过nvl和decode,没有用。

  5. query.setParameter("id", id==null?-1:id) // 无效。

我最后的选择是在 UserDao 文件中编写查询来替换用户文件中的 namedQuery。

谢谢 !

============================================

我的时间不多了,不得不放弃使用namedQuery。 我的解决方案:

# UserDao.java 

  public User getUser(Long id, String usename) {
        String getUser = "select u from user u where u.id " + Dao.isNull(id) 
                       + " And u.username " + Dao.isNull(username);
        Query query = Dao.entityManager.createQuery(getUser);
    }

# Dao.java

   public static String isNull(Object field) {
        if (field != null) {
                if (field instanceof String) {
                    return " = " + "'" + field + "'";
                } else {
                    return " = " + field;
                }

            } else {
                return " is NULL ";
            }
    }

您不能在运行时更改命名查询。 这样做会破坏命名查询的目的。 应使用标准 API 创建动态查询。

对在命名查询使用什么答案。

   from CountryDTO c where 
    ((:status is null and c.status is null) or c.status = :status) 
    and c.type =:type

尝试让布尔值检查空值。 它对我有用。

query.setParameter("idIsSet", id != null); 

query.setParameter("id", id); 

在命名查询中:

(:idIsSet = false or id = :id)

当 id 为空时,“idIsSet”为假。 所以 ":idIsSet = false" 变为 true 并且不会检查 id。

如果)在您的查询末尾是一个错误,请尝试不使用它

    @NamedQuery(name = "getUser", query = "select u from User u"
            + " where (:id is null or u.id = :id)"    
            + " And :username"

编辑

如果其他一切都失败了,这个快速的解决方法应该结合上面的空检查来完成(如果你在数据库中没有负 id)

query.setParameter("id", id == null ? -1 : id); 

检出<=>运算符。 它检查是否等于,还处理null。 在此处查看文档https://dev.mysql.com/doc/refman/8.0/en/comparison-operators.html#operator_equal-to

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM