2008-09-23 15 views
46

Używam Hibernuj dla ORM z mojej aplikacji Java do bazy danych Oracle (nie, że dostawca bazy danych ma znaczenie, możemy przełączyć się na inną bazę danych jeden dzień), i chcę pobrać obiekty z baza danych zgodnie z ciągami podanymi przez użytkownika. Na przykład, szukając ludzi, jeśli użytkownik szuka ludzi, którzy mieszkają w "fran", chcę móc dać jej ludzi w San Francisco.Wyszukiwanie niewrażliwe na wielkość liter przy użyciu Hibernate

SQL nie jest moją mocną stroną, a ja wolę kod budynku Hibernowanego Criteria od sztywno zakodowanych ciągów takich, jakie są. Czy ktoś może wskazać mi właściwy kierunek, jak to zrobić w kodzie, a jeśli to niemożliwe, jak powinien wyglądać zakodowany kod SQL?

Dzięki

Yuval = 8-)

Odpowiedz

67

Aby opisać prosty przypadek, spójrz na Restrictions.ilike(), który przeprowadza wyszukiwanie bez rozróżniania wielkości liter.

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

Dzięki ... nie wiedziałem, że istniały w Hibernate = 8-) – Yuval

+9

A dla każdego, kto szuka odpowiednika NHibernate, spróbuj 'InsensitiveLike()' –

+6

Po prostu wypróbowałem to. i nie zachowuje się bez uwzględnienia wielkości liter –

0

Większość sortowania domyślna baza danych nie jest uwzględniana wielkość liter, ale w świecie SQL Server może być ustawiony na przykład w bazie danych, a poziomem kolumnowej .

0

Można patrzeć na użycie Compassa owijającego nad lucene.

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

dodając kilka adnotacji do obiektów w domenie masz osiągnięcia tego rodzaju rzeczy.

Compass zapewnia prosty interfejs API do pracy z Lucene. Jeśli wiesz, jak korzystać z ORM, poczujesz się jak w domu z Compass za pomocą prostych operacji zapisywania i usuwania zapytania &.

Z samej witryny. "Kompilacja Kompasu, w oparciu o Lucene, upraszcza powszechne wzorce korzystania z Lucene, takie jak wyszukiwanie w stylu google, aktualizacje indeksu, a także bardziej zaawansowane koncepcje, takie jak buforowanie i podział indeksu (indeksy podrzędne) .Compass korzysta również z wbudowanych optymalizacji dla jednoczesnych zatwierdzeń i łączy. "

Użyłem tego w przeszłości i uważam to za świetne.

3

Zwykłe podejście do ignorowania sprawy jest konwersja obie wartości bazy danych i wartości wejściowej do górnej lub dolnej przypadku - wypadkowa sql miałby coś takiego

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

W kryteriach stan hibernacji restrictions.like (.. .). ignoreCase()

jestem bardziej zaznajomieni z NHibernate tak składnia może nie być w 100% dokładne

jakiegoś więcej informacji można znaleźć pro hibernate 3 extract i hibernate docs 15.2. Narrowing the result set

+0

Dla wersji hibernacyjnej 3.6.1 sekcja zwężająca zestaw wyników to 17.2. [Link] (http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#querycriteria-narrowing) – zmf

+0

Sir, oba linki są nieprawidłowe. –

9

Jeśli używasz Wiosny HibernateTemplate interakcję z Hibernate, oto jak można zrobić szafkowy niewrażliwe wyszukiwanie na adres e-mail użytkownika:

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

Ten komentarz naprawdę pomógł, W mojej aplikacji mam kod w następujący sposób: 'Użytkownik u = new User(); u.setUsername (nazwa użytkownika); Lista list = HibernateTemplate.findByExample () ', aby znaleźć użytkownika z bazy danych. Ale to bierze nazwę użytkownika w przypadku, gdy ją podaję. Ale chciałem napisać kwerendę, która wykonuje wyszukiwanie bez rozróżniania wielkości liter, więc użyłem znalezienia pokazanego przez SamS w następujący sposób: 'List list = HibernateTemplate.find (" od użytkownika, gdzie upper (nazwa użytkownika) =? ", U.getUsername() .toUpperCase()); ' – amit

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

Można to zrobić także za pomocą kryterium Przykład, w pakiecie 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(); 
} 

Jeszcze jeden sposób, który uważam za przydatny do osiągnięcia powyższych.