使用 Hibernate 进行不区分大小写的搜索

Posted

技术标签:

【中文标题】使用 Hibernate 进行不区分大小写的搜索【英文标题】:Case-insensitive search using Hibernate 【发布时间】:2010-09-12 08:16:47 【问题描述】:

我正在使用 Hibernate 将我的 Java 应用程序的 ORM 用于 Oracle 数据库(不是数据库供应商很重要,我们可能有一天会切换到另一个数据库),我想根据用户提供的从数据库中检索对象字符串。例如,在搜索人员时,如果用户正在寻找住在“弗兰”的人,我希望能够给她在旧金山的人。

SQL 不是我的强项,我更喜欢 Hibernate 的 Criteria 构建代码而不是硬编码字符串。谁能指出我在代码中如何做到这一点的正确方向,如果不可能,硬编码的 SQL 应该是什么样子?

谢谢,

尤瓦尔=8-)

【问题讨论】:

【参考方案1】:

对于您描述的简单情况,请查看 Restrictions.ilike(),它执行不区分大小写的搜索。

Criteria crit = session.createCriteria(Person.class);
crit.add(Restrictions.ilike('town', '%fran%');
List results = crit.list();

【讨论】:

谢谢...不知道 Hibernate 中存在 ilike =8-) 对于任何寻找 NHibernate 等效项的人,请尝试 'InsensitiveLike()' 我刚试过这个。并且它的行为不区分大小写 嗯...首选 MatchMode.ANYWHERE 而不是 '%' 请注意,如果您从 Eq 切换到 Like,您还将启用通配符,因此 oracle 中的下划线等匹配任何字符。【参考方案2】:
Criteria crit = session.createCriteria(Person.class);
crit.add(Restrictions.ilike('town', 'fran', MatchMode.ANYWHERE);
List results = crit.list();

【讨论】:

MatchMode.ANYWHERE 有什么用?它将匹配字符串中任何位置的模式。但它也会提供不区分大小写的搜索。 (比如如果我搜索狮子 - 它也会显示狮子的结果)【参考方案3】:

如果您使用 Spring 的 HibernateTemplate 与 Hibernate 进行交互,那么您将如何对用户的电子邮件地址进行不区分大小写的搜索:

getHibernateTemplate().find("from User where upper(email)=?", emailAddr.toUpperCase());

【讨论】:

这条评论真的很有帮助,在我的应用程序中,我的代码如下:User u = new User(); u.setUsername(username); List<User> list = HibernateTemplate.findByExample(<u>) 从数据库中查找用户。但在我给它的情况下,这是使用用户名。但我想编写一个执行不区分大小写搜索的查询,所以我使用了 SamS 所示的查找,如下所示:List<User> list = HibernateTemplate.find("from User where upper(username)=?", u.getUsername().toUpperCase());【参考方案4】:

您也不必输入“%”通配符。你可以传入MatchMode (docs for previous releases here) 来告诉搜索如何表现。 STARTANYWHEREEXACTEND 匹配是选项。

【讨论】:

【参考方案5】:

忽略大小写的常用方法是将数据库值和输入值都转换为大写或小写 - 生成的 sql 会有类似

select f.name from f where TO_UPPER(f.name) like '%FRAN%'

在休眠条件限制.like(...).ignoreCase()

我更熟悉 Nhibernate,所以语法可能不是 100% 准确

有关更多信息,请参阅 pro hibernate 3 extract 和 hibernate docs 15.2. Narrowing the result set

【讨论】:

对于休眠版本 3.6.1,用于缩小结果集的部分是 17.2。 Link 先生,这两个链接都无效。【参考方案6】:

这也可以使用 org.hibernate.criterion 包中的标准示例来完成。

public List findLike(Object entity, MatchMode matchMode) 
    Example example = Example.create(entity);
    example.enableLike(matchMode);
    example.ignoreCase();
    return getSession().createCriteria(entity.getClass()).add(
            example).list();

这只是我认为对完成上述任务有用的另一种方式。

【讨论】:

【参考方案7】:

自 Hibernate 5.2 session.createCriteria 已弃用。以下是使用 JPA 2 CriteriaBuilder 的解决方案。它使用likeupper

    CriteriaBuilder builder = session.getCriteriaBuilder();
    CriteriaQuery<Person> criteria = builder.createQuery(Person.class);
    Root<Person> root = criteria.from(Person.class);

    Expression<String> upper = builder.upper(root.get("town"));
    criteria.where(builder.like(upper, "%FRAN%"));

    session.createQuery(criteria.select(root)).getResultList();

【讨论】:

【参考方案8】:

大多数默认数据库排序规则不区分大小写,但在 SQL Server 世界中,它可以在实例、数据库和列级别进行设置。

【讨论】:

【参考方案9】:

您可以查看在 lucene 之上使用 Compass 包装器。

http://www.compass-project.org/

通过向您的域对象添加一些注释,您可以实现此类目标。

Compass 为使用 Lucene 提供了一个简单的 API。如果您知道如何使用 ORM,那么您会对 Compass 感到宾至如归,只需简单的保存、删除和查询操作即可。

来自网站本身。 “在 Lucene 之上构建,Compass 简化了 Lucene 的常见使用模式,例如 google 风格的搜索、索引更新以及更高级的概念,例如缓存和索引分片(子索引)。Compass 还使用内置优化来实现并发提交和合并。”

我以前用过这个,感觉很棒。

【讨论】:

以上是关于使用 Hibernate 进行不区分大小写的搜索的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 htmx 在 django 中进行不区分大小写的主动搜索

NSPredicate 使用 CloudKit 进行不区分大小写的字符串搜索

如何使用 less 使用模式修饰符进行不区分大小写的搜索?

IOS / Objective-C:使用StringByReplacingOccurrencesOfString进行不区分大小写搜索

如何进行不区分大小写的搜索。 Xamarin sqlite

使用 Amazon Dynamodb 进行不区分大小写的查询