开发者

How to use regular expressions with Hibernate/Oracle

I'm trying to implement a web service which accepts a list of strings, each of which is a regular expression. These need to be compared against six columns of a database, and any rows which match need to be returned.

I believe Oracle has a regexp_like() function which I might be able to use, but I'm looking for the best way to do this using Hibernate, so I'm not working against the persistence engine.

I started with something like this, in which the participants collection contains the regular expressions:

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

This doesn't work because "in" won't do what I want, and this does not appear to tell Hibernate to use a regular expression match.

This is the only answer I've come up with, but it looks really ugly:

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("r开发者_运维百科egexp_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);
}

I'm trying to push as much of this over to Oracle as I can. This appraoch seems likely to work, but putting the restrictions in without using parameters means I'm losing a lot of potential efficiency. Can anyone see a better way to do this? For simplicity, I'm trusting the regular expressions that are being passed to me.


There's nothing in the hibernate docs for performing regular expression queries (using HQL or Criteria queries). The approach using the sqlRestrictions should probably be changed to one of the overloaded methods to avoid a SQL Injection vulnerability.

Example code:

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


Similar working example

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜