Проблема с дизъюнкцией в DetachedCriteria - PullRequest
0 голосов
/ 28 марта 2012

Я получу три списка и 2 оператора op1, op2, которые могут быть «ИЛИ», «И», «И НЕ» .. Мне нужно сформировать запрос, подобный этому

например, рассмотрим сотрудника таблицы, я получу три списка List1, list2, list3 из emp_id's

select emp_num , emp_dpt , emp_name

from employee

where
    emp_id in (list1)

    op1

    emp_id in (list2)

    op2

    emp_id in (list3)

Я написал два метода

public List<Employee> getRequestedEmployee(List<Long> list1 , List<Long> list2, List<Long> list3 , String op1 , String op2) {

    DetachedCriteria dc = DetachedCriteria.forClass(Employee)

    if (!CollectionUtils.isEmpty(list1))
    {
        dc.add(Restrictions.in(list1,emp_id));
    }

    if(!CollectionUtils.isEmpty(list3)
    {
        dc = getCriteria(dc , list2 , op1);
    }

    if(!CollectionUtils.isEmpty(list3)
    {
        dc = getCriteria(dc , list3 , op2);
    }
}

private DetachedCriteria getCriteria( DetachedCriteria dc , List<long> empIdList, String operator)
{
    if(!CollectionUtils.IsEmpty(empIdList))
    {
        if("and".equals(operator))
        {
            Conjunction andOp = Restrictions.Conjunction();
            andOp.add(Restrictions.in(empIdList));
            dc.add(andOp);
        }
        else if("or".equals(operator))
        {
            Disjunction orOp = restrictions.disjunction();
            orOp.add(Restrictions.in(empIdList))
            dc.add(andOp);
        }
        else
        {
             dc.add(Restrictions.not(empIdList));
        }
        return dc;
    }
}

У меня проблема с дизъюнкцией. Когда я прохожу, ИЛИ интерпретирует как И ...

например, если я прохожу op1 = and, op2 = or он формируется так

select emp_num , emp_dpt , emp_name

from employee

where
    emp_id in (list1)

    and

    emp_id in (list2)

    and

    emp_id in (list3)

но я хочу

select emp_num , emp_dpt , emp_name

from employee

where
    emp_id in (list1)

    and

    emp_id in (list2)

    or

    emp_id in (list3)

где бы я ни ожидал или ставил, и неважно, op1 или op2

Нужна помощь ...

1 Ответ

0 голосов
/ 08 апреля 2012

And происходит от dc.add().Каждое добавление будет одним критерием, который соединяется с и.дизъюнкция с 1 аргументом является в основном noop, потому что crit and <nothing> = crit.Необходимо накапливать критерии на уровне критерия, а не на уровне запроса / критерия

public List<Employee> getRequestedEmployee(List<Long> list1 , List<Long> list2, List<Long> list3 , String op1 , String op2)
{
    ICriterion crit = null;

    if (!CollectionUtils.isEmpty(list1))
    {
        crit = Restrictions.in("emp_id", list1));
    }

    if(!CollectionUtils.isEmpty(list3)
    {
        crit = addCriteria(crit , list2 , op1);
    }

    if(!CollectionUtils.isEmpty(list3)
    {
        crit = addCriteria(crit , list3 , op2);
    }

    DetachedCriteria query = DetachedCriteria.forClass(Employee);
    if (crit != null)
    {
        query = query.add(crit);
    }
    return query;
}

private ICriterion addCriteria( ICriterion existingCrit, List<long> empIdList, String operator)
{
    if(CollectionUtils.IsEmpty(empIdList))
    {
        return existingCrit;
    }

    ICriterion crit = Restrictions.in("emp_Id", empIdList);

    if(existingCrit == null)
    {
        return crit;
    }
    else if("and".equals(operator))
    {
        return Restrictions.conjunction()
            .add(existingCrit);
            .add(crit);
    }
    else if("or".equals(operator))
    {
        return Restrictions.disjunction()
            .add(existingCrit);
            .add(crit);
    }
    else // "not"
    {
        return Restrictions.conjunction()
            .add(existingCrit);
            .add(Restrictions.not(crit));
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...