2010-12-02 4 views
4

Ich versuche, einen Webdienst zu implementieren, der eine Liste von Zeichenfolgen akzeptiert, von denen jeder ein regulärer Ausdruck ist. Diese müssen mit sechs Spalten einer Datenbank verglichen werden, und alle übereinstimmenden Zeilen müssen zurückgegeben werden.Verwendung regulärer Ausdrücke mit Hibernate/Oracle

Ich glaube, Oracle eine REGEXP_LIKE() Funktion hat, die ich zu verwenden könnte fähig sein, aber ich bin auf der Suche nach dem besten Weg, dies mit Hibernate zu tun, also arbeite ich nicht gegen die Persistenz-Engine.

begann ich mit so etwas wie dies, in dem die Teilnehmer Sammlung die regulären Ausdrücke enthält:

List<Message> messages = new ArrayList<Message>(); 
List<Message> m1 = ((Session) entityManager.getDelegate()) 
    .createCriteria(MessageSSR.class).add(Restrictions.or(
      Restrictions.in("Node2Id", participants), 
      Restrictions.in("Node2Id", participants))).list(); 
List<Message> m2 = ((Session) entityManager.getDelegate()) 
    .createCriteria(MessageSSR.class).add(Restrictions.or(
      Restrictions.in("Node3Id", participants), 
      Restrictions.in("Node4Id", participants))).list(); 
List<Message> m3 = ((Session) entityManager.getDelegate()) 
    .createCriteria(MessageSSR.class).add(Restrictions.or(
      Restrictions.in("Node5Id", participants), 
      Restrictions.in("Node6Id", participants))).list(); 
messages.addAll(m1); 
messages.addAll(m2); 
messages.addAll(m3); 

Das funktioniert nicht, weil „in“ nicht tun, was ich will, und dies scheint nicht Hibernate, um eine Übereinstimmung mit regulären Ausdrücken zu verwenden

Dies ist die einzige Antwort, die ich habe kommen mit, aber es sieht wirklich hässlich:

List<Message> messages = new ArrayList<Message>(); 
for (String re : participants) { 
    List<Message> m1 = ((Session) entityManager.getDelegate()) 
     .createCriteria(MessageSSR.class) 
     .add(Restrictions.or(
       Restrictions.sqlRestriction("regexp_like(NODE_1, " + re + ")"), 
       Restrictions.sqlRestriction("regexp_like(NODE_2, " + re + ")") 
     )).list(); 
    List<Message> m2 = ((Session) entityManager.getDelegate()) 
     .createCriteria(MessageSSR.class) 
     .add(Restrictions.or(
       Restrictions.sqlRestriction("regexp_like(NODE_3, " + re + ")"), 
       Restrictions.sqlRestriction("regexp_like(NODE_4, " + re + ")") 
     )).list(); 
    List<Message> m3 = ((Session) entityManager.getDelegate()) 
     .createCriteria(MessageSSR.class) 
     .add(Restrictions.or(
       Restrictions.sqlRestriction("regexp_like(NODE_5, " + re + ")"), 
       Restrictions.sqlRestriction("regexp_like(NODE_6, " + re + ")") 
     )).list(); 
    messages.addAll(m1); 
    messages.addAll(m2); 
    messages.addAll(m3); 
} 

Ich versuche, so viel von diesem über Oracle zu schieben, wie ich kann. Diese Appraach scheint zu funktionieren, aber die Einschränkungen ohne Parameter zu setzen bedeutet, dass ich eine Menge potentielle Effizienz verliere. Kann jemand einen besseren Weg sehen, dies zu tun? Der Einfachheit halber vertraue ich den regulären Ausdrücken, die mir übergeben werden.

Antwort

7

Es gibt nichts in den Hibernate-Dokumenten zum Ausführen von Abfragen für reguläre Ausdrücke (mithilfe von HQL- oder Criteria-Abfragen). Der Ansatz mit der sqlRestrictions sollte wahrscheinlich in eine der überladenen Methoden geändert werden, um eine SQL Injection-Schwachstelle zu vermeiden.

Beispielcode:

Restrictions.sqlRestriction("regexp_like({alias}.NODE_1, ?)", re, Hibernate.STRING) 
+0

Funktioniert prima, wenn Sie die verwenden müssen: alpha: da Überschreiben des Bediener Oracle bietet: mit \\: nie schienen zu funktionieren. –

0

ähnliches Arbeitsbeispiel

Criterion criterion = Restrictions.sqlRestriction("regexp_like (column_name, ?, 'i')", "(^|\\s)"+searchValue+"($|\\s|.$)", StringType.INSTANCE);