¿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".

ScArcher2
fuente

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í .

sblundy
fuente
¡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);
Rob Oxspring
fuente
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.

Dharmender Rawat
fuente
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.
Dharmender Rawat
fuente
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)));
Geir-Tore Lindsve
fuente
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();
Tiago Medici
fuente
¿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 (
                ?, ?, ?
            )
        ) 
ronak
fuente
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()])));
Gaspar
fuente