Case-onsensitiewe soek met behulp van Hibernate
-
02-07-2019 - |
Vra
Ek gebruik Hibernate vir ORM van my Java app om 'n Oracle databasis (nie dat die databasis verkoper sake, kan ons skakel na 'n ander databasis eendag), en ek wil voorwerpe uit die databasis te haal volgens die gebruiker verskaf snare. Byvoorbeeld, wanneer jy soek vir mense, as die gebruiker is op soek na mense wat in 'Fran' leef, ek wil in staat wees om haar volk te gee in San Francisco.
SQL is nie my sterk pak, en ek verkies Hibernate se Criteria
gebou-kode vir hard-gekodeerde snare soos dit is. Kan iemand my wys in die regte rigting oor hoe om dit te doen in kode, en indien moontlik, hoe die harde-gekodeerde SQL moet lyk?
Dankie,
Yuval = 8 -)
Oplossing
Vir die eenvoudige geval wat jy beskryf, kyk na Restrictions.ilike (), wat 'n geval-onsensitiewe soek nie.
Criteria crit = session.createCriteria(Person.class);
crit.add(Restrictions.ilike('town', '%fran%');
List results = crit.list();
Ander wenke
Criteria crit = session.createCriteria(Person.class);
crit.add(Restrictions.ilike('town', 'fran', MatchMode.ANYWHERE);
List results = crit.list();
As jy die lente se HibernateTemplate gebruik om met Hibernate, hier is hoe jy 'n geval onsensitiewe soek sal doen oor e-pos adres van die gebruiker:
getHibernateTemplate().find("from User where upper(email)=?", emailAddr.toUpperCase());
Jy hoef ook nie in die '%' wildcards te sit. Jy kan slaag MatchMode (< a href = "http://www.hibernate.org/hib_docs/v3/api/org/hibernate/criterion/MatchMode.html" rel = "nofollow noreferrer"> docs vir vorige weergawes hier ) in te vertel die soektog hoe om op te tree. START
, ANYWHERE
, EXACT
, en END
wedstryde is die opsies.
Die gewone benadering tot ignoreer geval is om beide die databasis waardes en die insetwaarde te boonste of onderste geval omskep - die gevolglike SQL sou so iets
hêselect f.name from f where TO_UPPER(f.name) like '%FRAN%'
In hiberneer kriteria restrictions.like (...). IgnoreCase ()
Ek is meer vertroud met Nhibernate so die sintaksis nie 100% akkuraat kan wees
vir 'n paar meer inligting sien pro hiberneer 3 uittreksel en hiberneer docs 15.2. Vernouing van die resultaat stel
Die meeste standaard databasis collations is nie kassensitief, maar in die SQL Server wêreld dit kan ingestel word op aandrang, die databasis, en die kolom vlak.
Jy kan kyk na die gebruik van Compass 'n wrapper bo Lucene.
http://www.compass-project.org/
Deur die toevoeging van 'n paar notas om jou domein voorwerpe wat jy kry hierdie soort ding te bereik.
Compass bied 'n eenvoudige API vir die werk met Lucene. As jy weet hoe om 'n ORM gebruik, dan sal jy dadelik tuis met Compass met 'n eenvoudige operasies vir red voel, en verwyder & navraag.
Van die webwerf self. "Gebou op die top van Lucene, Compass vergemaklik algemene gebruik patrone van Lucene soos Google-styl soek, indeks updates sowel as meer gevorderde konsepte soos caching en indeks sharding (sub-indekse). Compass gebruik ook gebou in optimalisaties vir gelyktydige begaan samevoegings. "
Ek het hierdie gebruik in die verlede en ek vind dit baie goed.
Dit kan ook gedoen word met behulp van die maatstaf Voorbeeld, in die org.hibernate.criterion pakket.
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();
}
Net nog 'n manier wat ek nuttig om die bogenoemde te bereik vind.