2010-12-02 6 views
4

J'essaye d'implémenter un service Web qui accepte une liste de chaînes, chacune étant une expression régulière. Ceux-ci doivent être comparés à six colonnes d'une base de données, et toutes les lignes qui correspondent doivent être retournées.Comment utiliser les expressions régulières avec Hibernate/Oracle

Je crois que Oracle a une fonction regexp_like() que je pourrais être en mesure d'utiliser, mais je suis à la recherche de la meilleure façon de le faire en utilisant Hibernate, donc je ne travaille pas contre le moteur de persistance.

J'ai commencé avec quelque chose comme ça, où la collection participants contient les expressions régulières:

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

Cela ne fonctionne pas parce que « dans » ne fera pas ce que je veux, et cela ne semble pas pour dire à Hibernate d'utiliser une correspondance d'expression régulière.

Ceci est la seule réponse que je suis venu avec, mais il semble vraiment moche:

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

Je suis en train de pousser autant de ce vers Oracle que je peux. Cette approche semble fonctionner, mais mettre les restrictions sans utiliser de paramètres signifie que je perds beaucoup d'efficacité potentielle. Quelqu'un peut-il voir une meilleure façon de le faire? Pour plus de simplicité, je fais confiance aux expressions régulières qui me sont transmises.

Répondre

7

Il n'y a rien dans les documents hibernate pour effectuer des requêtes d'expressions régulières (en utilisant des requêtes HQL ou Criteria). L'approche utilisant le sqlRestrictions devrait probablement être changée en l'une des méthodes surchargées pour éviter une vulnérabilité d'injection de SQL.

code Exemple:

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

fonctionne très bien si vous devez utiliser l': alpha: l'opérateur Oracle fournit depuis redéfinissant la: avec \\: ne semblait pas fonctionner. –

0

exemple de travail similaires

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