使用like运算符进行Hibernate HQL查询

18

请查看以下映射

@Entity
public class User {

    private Integer id;

    @Id;
    private Integer getId() {
        return this.id;
    }

}

注意 id 是一个整数。现在我需要使用 like 运算符来构建这个 HQL 查询。

Query query = sessionFactory.getCurrentSession().createQuery("from User u where u.id like :userId");

注意:这里使用的是like操作符,而不是=(等于操作符)。

然后我使用

List<User> userList = query.setParameter("userId", userId + "%").list();

但是不起作用,因为Hibernate抱怨调用User.id的getter方法时出现了IllegalArgumentException异常。

即使我使用

query.setString("userId", userId + "%");

它不起作用。

我应该使用什么来传递查询?


您使用哪个数据库引擎? - Juha Syrjälä
@Arthur - 不回答你的问题(看起来你已经自己解决了),但我必须问一下 - 为什么?我真的很感兴趣 - 你有什么用例需要使用LIKE比较,而这似乎是一个代理键? - ChssPly76
@ChssPly76 - 你好Chss。这是一个遗留系统。它是树形结构,父组ID匹配所有子ID。例如,如果我的组ID = 22100,我想检索其子代,通过匹配221前缀,我使用 >>> 像 '221%' 这样的方法。 - Arthur Ronald
1
@Arthur - 我明白了。考虑到底层列是数字的(并且作为PK,很可能被索引),您很可能会在进行数字比较时获得更好的性能。例如,在上面的示例中,您将执行 where userId > 22100 and userId < 22200。根据您的数据库引擎和表大小,差异可能会非常显着(因为此处将使用索引,但不会用于LIKE)。 - ChssPly76
@ChssPly76 感谢您的回复。这是一个非常好的想法。在这种情况下,我认为我需要使用正则表达式来检索其前缀。但是由于有些情况下我需要检索一些子元素,而不是全部子元素。因此,您的解决方案可能无法按预期工作。 - Arthur Ronald
@ChssPly76 我会使用正则表达式来获取其前缀(221)和后缀(00)。然后我需要获取下一个前缀(222)。然后,按照建议比较这两个值。 - Arthur Ronald
2个回答

32
根据Hibernate参考文献: str()用于将数字或时间值转换为可读字符串。 所以当我使用:
from User u where str(u.id) like :userId

它的运行良好


是的,str()方法给了我解决方案。 我遇到了同样的问题,因为我的实体类有LONG字段。我使用Hibernate的like操作符,但它给了我一个转换异常。通过使用Hibernate的str()方法,我找到了解决方案,并使用了Hibernate查询。请查看以下示例查询:select b.billNumber from Bill b where str(b.billNumber) like :billNumber").setString("billNumber,your_parameter).list(); - saminda konkaduwa

7

通常情况下,LIKE操作符用于文本数据,即VARCHAR或CHAR列,而您有数字id列(INTEGER)。

也许您可以尝试将id字段映射为字符串并在查询中使用该字段。这可能会或可能不会在您的数据库引擎中起作用。请注意,您应该通过setId()处理所有更新,并考虑idAsString字段为只读。

@Entity
public class User {
private Integer id; private String idAsString;
@Id; private Integer getId() { return this.id; }
private void setId(Integer id) { this.id = id; }
@Column(name="id", insertable=false, updatable=false) private String getIdAsString() { return this.idAsString; }
private void setIdAsString(String idAsString) { this.idAsString = idAsString; } }

然后查询将是:

Query query = sessionFactory.getCurrentSession().createQuery("from User u where u.idAsString like :userId");
List<User> userList = query.setParameter("userId", userId + "%").list();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接