2008-09-23 30 views
46

Estoy usando Hibernate para ORM de mi aplicación Java en una base de datos Oracle (no es que el proveedor de la base de datos importe, podemos cambiar a otra base de datos un día) y quiero recuperar objetos del base de datos de acuerdo con cadenas proporcionadas por el usuario. Por ejemplo, cuando busco personas, si el usuario está buscando personas que vivan en 'fran', quiero poder darle a su gente en San Francisco.Búsqueda insensible a mayúsculas/minúsculas usando Hibernate

SQL no es mi fuerte, y prefiero el código de construcción de Hibernate Criteria a las cadenas codificadas como están. ¿Puede alguien señalarme en la dirección correcta sobre cómo hacer esto en el código, y si es imposible, cómo debería ser el SQL codificado?

Gracias,

Yuval = 8-)

Respuesta

67

Para el caso simple que describe, consulte Restrictions.ilike(), que hace una búsqueda insensible a mayúsculas y minúsculas.

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

Gracias ... no sabía que ilike existía en Hibernate = 8-) – Yuval

+9

Y para cualquiera que busque el equivalente de NHibernate, pruebe 'InsensitiveLike()' –

+6

. Probé esto. y no se comporta sin distinguir entre mayúsculas y minúsculas –

0

La mayoría de las intercalaciones de base de datos por defecto no son mayúsculas y minúsculas, pero en el mundo de SQL Server que se pueden establecer en el ejemplo, la base de datos, y el nivel de la columna .

0

Podrías mirar usando una brújula Compass por encima de lucene.

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

Mediante la adición de un par de anotaciones a su dominio objetos se obtiene lograr este tipo de cosas.

Compass proporciona una API simple para trabajar con Lucene. Si sabe cómo usar un ORM, entonces se sentirá como en casa con Compass con operaciones simples para guardar y eliminar la consulta &.

Desde el sitio en sí. "Compass simplifica los patrones de uso comunes de Lucene, como la búsqueda al estilo de Google, las actualizaciones de índices y otros conceptos más avanzados como el almacenamiento en caché y la división de índices (subíndices). Compass también utiliza optimizaciones integradas para confirmaciones concurrentes y se fusiona ".

Lo he usado en el pasado y me parece genial.

3

El enfoque habitual de ignorar caso es convertir tanto los valores de base de datos y el valor de entrada a mayúsculas o minúsculas - SQL resultante tendría algo así como

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

En los criterios de hibernación restrictions.like (.. .). ignoreCase()

estoy más familiarizado con Nhibernate lo que la sintaxis puede no ser fiable al 100%

para algunos más información ver pro hibernate 3 extract y hibernate docs 15.2. Narrowing the result set

+0

Para la versión 3.6.1 de hibernación, la sección para reducir el conjunto de resultados es 17.2. [Enlace] (http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#querycriteria-narrowing) – zmf

+0

Señor, ambos enlaces no son válidos. –

4

Tampoco tiene que poner los comodines '%'. Puede pasar MatchMode (docs for previous releases here) para indicarle a la búsqueda cómo comportarse. START, ANYWHERE, EXACT y END coincidencias son las opciones.

9

Si utiliza HibernateTemplate de primavera para interactuar con Hibernate, aquí es cómo se haría una búsqueda que ignore en la dirección de correo electrónico de un usuario:

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

Este comentario realmente ayudó, En mi aplicación tengo el código de la siguiente manera: 'Usuario u = nuevo Usuario(); u.setUsername (username); Lista list = HibernateTemplate.findByExample () 'para encontrar al usuario de la base de datos. Pero esto es tomar el nombre de usuario en el caso que lo estoy dando. Pero quería escribir una consulta que realizara una búsqueda insensible a mayúsculas/minúsculas así que usé el hallazgo como lo muestra SamS de la siguiente manera: 'List list = HibernateTemplate.find (" desde User donde upper (username) =? ", U.getUsername() .toUpperCase()); ' – amit

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

Esto también se puede hacer utilizando el criterio ejemplo, en el paquete 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(); 
} 

Solo otra forma que me parece útil para lograr lo anterior.

Cuestiones relacionadas