¿Cómo se combinan los criterios "O" cuando se utiliza una consulta de criterios con hibernación?


79

Estoy tratando de hacer un "O" básico en tres campos usando una consulta de criterios de hibernación.

Ejemplo

class Whatever{
 string name;
 string address;
 string phoneNumber;
}

Me gustaría crear una consulta de criterios donde mi cadena de búsqueda podría coincidir con "nombre" o "dirección" o "número de teléfono".

Respuestas:


133

Quieres usar Restrictions.disjuntion(). Al igual que

session.createCriteria(Whatever.class)
    .add(Restrictions.disjunction()
        .add(Restrictions.eq("name", queryString))
        .add(Restrictions.eq("address", queryString))
        .add(Restrictions.eq("phoneNumber", queryString))
    );

Vea el documento de Hibernate aquí .


¡Eso es perfecto gracias! Finalmente encontré un ejemplo en línea, pero me alegra que esté aquí para referencia futura.
ScArcher2

8
¿y si lo que quería (name = x AND address = y) OR (phoneNumber = z)?
Kevin Meredith

71

Suponiendo que tiene una sesión de hibernación a mano, algo como lo siguiente debería funcionar:

Criteria c = session.createCriteria(Whatever.class);
Disjunction or = Restrictions.disjunction();
or.add(Restrictions.eq("name",searchString));
or.add(Restrictions.eq("address",searchString));
or.add(Restrictions.eq("phoneNumber",searchString));
c.add(or);

4
Me gusta la sintaxis de crear la disyunción y nombrarla o. Es mucho más legible que la otra solución.
ScArcher2

Esto fue genial :) También de acuerdo con @ ScArcher2, es muy legible e hizo que el ejemplo más complicado que tenía que hacer fuera mucho más fácil de entender.
Dustin Jensen

12
    //Expression :  (c1 AND c2) OR (c3)      


     Criteria criteria = session.createCriteria(Employee.class);

      Criterion c1 = Restrictions.like("name", "%e%");
      Criterion c2 = Restrictions.ge("salary", 10000.00);
      Criterion c3 = Restrictions.like("name", "%YYY%");
      Criterion c4 = Restrictions.or(Restrictions.and(c1, c2), c3);
      criteria.add(c4);

// Se puede hacer lo mismo para (c1 O c2) Y c3, o cualquier expresión compleja.


6
//Expression :  (c1 AND c2) OR (c3)      


 Criteria criteria = session.createCriteria(Employee.class);

  Criterion c1 = Restrictions.like("name", "%e%");
  Criterion c2 = Restrictions.ge("salary", 10000.00);
  Criterion c3 = Restrictions.like("name", "%YYY%");
  Criterion c4 = Restrictions.or(Restrictions.and(c1, c2), c3);
  criteria.add(c4);

  //Same thing can be done for (c1 OR c2) AND c3, or any complex expression.

3

En caso de que alguien se tope con esto con la misma pregunta para NHibernate:

ICriteria c = session.CreateCriteria(typeof (Whatever))
    .Add(Expression.Disjunction()
        .Add(Expression.Eq("name", searchString))
        .Add(Expression.Eq("address", searchString))
        .Add(Expression.Eq("phoneNumber", searchString)));

1

Las condiciones se pueden aplicar usando el o / y en diferentes niveles de la consulta usando disyunción

Criteria query = getCriteria("ENTITY_NAME");
query.add(Restrictions.ne("column Name", current _value));

Disjunction disjunction = Restrictions.disjunction();

if (param_1 != null)
    disjunction.add(Restrictions.or(Restrictions.eq("column Name", param1)));

if (param_2 != null)
    disjunction.add(Restrictions.or(Restrictions.eq("column Name", param_2)));

if (param_3 != null)
    disjunction.add(Restrictions.or(Restrictions.eq("column Name", param_3)));
if (param_4 != null && param_5 != null)
    disjunction.add(Restrictions.or(Restrictions.and(Restrictions.eq("column Name", param_4 ), Restrictions.eq("column Name", param_5 ))));

if (disjunction.conditions() != null && disjunction.conditions().iterator().hasNext())
    query.add(Restrictions.and(disjunction));

return query.list();

¿Es posible obtener nulos para todos los elementos que no se encuentran en la base de datos?
violín

Es consistente: se devuelve una lista con todos los resultados, los haya o no.
Tiago Medici

1

Esto es lo que funcionó para mí para una condición OR, que también con una condición IN y no la respuesta más votada en esta discusión:

criteria.add( Restrictions.or(
                    Restrictions.eq(ch.getPath(ch.propertyResolver().getXXXX()), "OR_STRING"),
                        Restrictions.in(ch.getPath(ch.propertyResolver().getYYYY()), new String[]{"AA","BB","CC"})
                    ));

Consulta resultante:

  and (
            this_.XXXX=? 
            or this_.YYYY in (
                ?, ?, ?
            )
        ) 

1

Si alguien está usando CriteriaQuery en lugar de Criteria, puede poner todas sus expresiones en una Predicatelista y poner un OR por tamaño de predicados como este:

List<Predicate> predicates = new ArrayList<>();
if (...) {
  predicates.add(...);
}

criteriaQuery.where(cb.or(predicates.toArray(new Predicate[predicates.size()])));
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.