我想将两个参数传递给namedquery。一个是数字类型,另一个是字符串类型。它们都可以为空。
例如,(id = null,username =' joe')和(id = 1,username =' joe')是两个不同的结果。在namedQuery中,语法为" u.id为null"如果id为null,但是" u.id =:id"如果id不为null。我的问题是如何动态处理namedQuery中的id?
请检查我的示例代码:
1.User.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;
}
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;
}
}
=======================================
我尝试过:
这是遗留代码,我不想改变结构。所以我不想使用Criteria。
从User u中选择你的位置(:id为null或u.id =:id)和u.username =:username
//抛出异常:不一致的数据类型:预期的NUMBER有BINARY
从用户u中选择你,其中u.id = nullif(:id,null)和u.username =:username
//抛出异常:数据类型不一致:预期NUMBER有BINARY
我也尝试过nvl并在namedQuery中解码,没有用。
query.setParameter(&#34; id&#34;,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 ";
}
}
答案 0 :(得分:3)
您无法在运行时更改命名查询。这样做会破坏命名查询的目的。 应使用条件api创建动态查询。
请参阅this回答有关在命名查询中使用的内容。
from CountryDTO c where
((:status is null and c.status is null) or c.status = :status)
and c.type =:type
答案 1 :(得分:0)
如果查询结尾处的)
出错,请尝试不使用
@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);
答案 2 :(得分:0)
尝试让布尔值检查null。它对我有用。
query.setParameter("idIsSet", id != null);
query.setParameter("id", id);
在命名查询中:
(:idIsSet = false or id = :id)
当id为null时,“ idIsSet”为false。因此,“:idIsSet = false”变为true,并且不会检查ID。