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

时间:2020-03-06 14:35:39  来源:igfitidea点击:

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

SQL不是我的强项,我更喜欢Hibernate的Criteria构建代码,而不是硬编码的字符串。谁能指出正确的方向,说明如何在代码中执行此操作;如果不可能,则硬编码的SQL应该是什么样子?

谢谢,

尤瓦尔= 8-)

解决方案

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

我们可以看一下使用Compass在Lucene之上的包装器。

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

通过向域对象添加一些注释,我们可以实现这种目的。

Compass提供了一个与Lucene一起使用的简单API。如果我们知道如何使用ORM,那么使用Compass进行简单的保存,删除和查询操作就可以让我们感到宾至如归。

来自网站本身。
" Compass建立在Lucene的基础上,简化了Lucene的常用用法,例如Google式搜索,索引更新以及更高级的概念,例如缓存和索引分片(子索引)。合并。"

我过去曾经使用过它,并且发现它很棒。

忽略大小写的通常方法是将数据库值和输入值都转换为大写或者小写,结果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. 缩小结果集

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

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

我们也不必输入'%'通配符。我们可以传入MatchMode(此处为早期版本的文档),以告知搜索行为。可以选择"开始","任何地方","精确"和"结束"匹配项。

如果我们使用Spring的HibernateTemplate与Hibernate进行交互,则可以通过以下方式对用户的电子邮件地址进行不区分大小写的搜索:

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

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

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

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();
}

我认为对实现上述目标有用的另一种方式。