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

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

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

谢谢,

尤瓦尔=8-)

【问题讨论】:

    标签: sql hibernate select case-sensitive


    【解决方案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 extracthibernate 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 还使用内置优化来实现并发提交和合并。”

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2011-01-14
              • 1970-01-01
              • 2012-12-20
              • 2021-06-14
              • 1970-01-01
              • 1970-01-01
              • 2011-10-17
              • 1970-01-01
              相关资源
              最近更新 更多