我想在字段上使用通配符搜索,该字段是Long值(在Entity类中)和在数据库中的Integer.Here Contact是实体类,其具有字段:Id作为实体类中的Long值和作为数据库中的Integer 。以下是代码。
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Tuple> query = builder.createTupleQuery();
Root<Contact> root = query.from(Contact.class);
List<Predicate> predicates = new ArrayList<Predicate>();
if (searchCriteria.getContactId() != null) {
if(searchCriteria.getContactId().contains("%")){
predicates.add(builder.like(
(root.get(Contact_.id)),-->Note this line
builder.literal(searchCriteria.getContactId()+"%")));
}
}
这里builder.like将不接受root.get(Contact_.id),因为Contact_.id是一个long值。我们将在这里得到编译错误。这里searchCriteria.getContactId()是字符串值。
有没有办法将root.get(Contact_.id)转换为字符串类型?
public static volatile SingularAttribute<Contact, Long> id;
到目前为止,我已尝试过
((Expression<String>)(root.get(Contact_.id).as(String.class).
但我得到查询语法异常。它无法将其转换为完美语法。它给出了像 - &gt;这样的查询(强制转换(generatedAlias0.id as varchar(255))但不是(cast(generatedAlias0.id as string))当我查看日志时。
答案 0 :(得分:2)
当我使用类似标签进行搜索时,我找到了一个很好的解决上述问题的方法,它只使用了标准构建器。我已经尝试过它并且工作正常。 我们可以在下面的链接中找到它。
JPA: How to perform a LIKE with a NUMBER column in a static JPA MetaModel?
答案 1 :(得分:1)
JPA指定的一些CriteriaBuilder方法(例如,notLike,concat,substring,trim,lower,upper,length,locate)只能用于字符串,因此拒绝整数表达式:
predicates.add(
Expression<Long> idExpr = root.get(Contact_.id);
builder.like(idExpr), // error: Expression<String> is expected
builder.literal(searchCriteria.getContactId() + "%")
);
要解决此问题,您可以尝试使用Hibernate扩展,例如:
Criteria c = session.createCriteria(Contact.class);
c.add(Restrictions.sqlRestriction(" CAST(id AS varchar(255)) LIKE '1%'"));
List<Contact> entities = c.list();
Query q = session.createQuery("FROM Contact c WHERE STR(c.id) LIKE '1%'");
List<Contact> c= q.list();
SQLQuery q2 = session.createSQLQuery("SELECT * FROM Contact " +
"WHERE CAST(id AS varchar(255)) LIKE '1%'");
List<Contact> entities = q.getResultList();
看起来只有HQL有STR()
表达式,或者我在HCQ中找不到等价物。无论如何,HQL中使用的STR(c.id)
将被翻译为CAST(id AS VARCHAR(255))
子句。