简体   繁体   English

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

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

I want to pass two parameters to namedquery.我想将两个参数传递给namedquery。 One is number type and the other is String type.一种是数字类型,另一种是字符串类型。 They both could be null.他们都可以为空。

For instance, (id=null, username='joe') and (id=1, username='joe') are two different results.例如,(id=null, username='joe') 和 (id=1, username='joe') 是两个不同的结果。 In namedQuery, the syntax is "u.id is null" if id is null, but "u.id = :id" if id is not null.在 namedQuery 中,如果 id 为 null,则语法为“u.id is null”,如果 id 不为 null,则语法为“u.id = :id”。 My question is how to dynamically handle the id filed in namedQuery?我的问题是如何动态处理namedQuery中提交的id?

Please check my sample code:请检查我的示例代码:

1.User.java 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. UserDao.java用户道
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;
    }
}

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

What I have tried:我尝试过的:

  1. This is legacy code and I don't want to change the structure.这是遗留代码,我不想更改结构。 So I don't want to use Criteria.所以我不想使用 Criteria。

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

    // throw exception: inconsistent datatypes: expected NUMBER got BINARY // 抛出异常:不一致的数据类型:预期 NUMBER 得到 BINARY

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

    // Throw exception: inconsistent datatypes: expected NUMBER got BINARY // 抛出异常:不一致的数据类型:预期 NUMBER 得到 BINARY

  4. I also tried nvl and decode in namedQuery, didn't work.我也在namedQuery中尝试过nvl和decode,没有用。

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

My last choice will be writing query in UserDao file to replace namedQuery in User file.我最后的选择是在 UserDao 文件中编写查询来替换用户文件中的 namedQuery。

Thank you !谢谢 !

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

I am running out of time and have to give up using namedQuery.我的时间不多了,不得不放弃使用namedQuery。 My solution:我的解决方案:

# 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 ";
            }
    }

You cannot change the named query at run time.您不能在运行时更改命名查询。 Doing so would defeat the purpose of the named query.这样做会破坏命名查询的目的。 Dynamic queries should be created using the criteria api.应使用标准 API 创建动态查询。

See this answer on what to use in the named query.对在命名查询使用什么答案。

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

Try to let a boolean check the null.尝试让布尔值检查空值。 It worked for me.它对我有用。

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

query.setParameter("id", id); 

In the named query:在命名查询中:

(:idIsSet = false or id = :id)

When id is null, the "idIsSet" is false.当 id 为空时,“idIsSet”为假。 So ":idIsSet = false" turns into true and the id will not be checked.所以 ":idIsSet = false" 变为 true 并且不会检查 id。

If ) at the end of your query was a mistake, try without it如果)在您的查询末尾是一个错误,请尝试不使用它

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

EDIT编辑

If everything else fails, this quick workaround should do it (if you don't have negative ids in database) in combination with the above null check如果其他一切都失败了,这个快速的解决方法应该结合上面的空检查来完成(如果你在数据库中没有负 id)

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

Check out <=> operator. 检出<=>运算符。 It checks for equals and also handles null. 它检查是否等于,还处理null。 See the doc here https://dev.mysql.com/doc/refman/8.0/en/comparison-operators.html#operator_equal-to 在此处查看文档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