динамически поисковый запрос в HQL с необязательным параметром?

Я разрабатываю приложение, в котором мне нужна функция поиска, я хочу написать HQL-запрос, который динамически создается в соответствии с параметрами. В настоящее время у меня есть 4 параметра, при поиске все параметры требуются или требуются 1, 2 или 3 параметра в зависимости от того, как пользователь хочет искать.

public List<Plot> fetchSearchedPlots(int plotType, String plotSize, String min, String max)
    {
        Session session = sessionFactory.getCurrentSession();
        List<Plot> searchedLists = new ArrayList<Plot>();
        String query = "FROM Plot where type = ? and size = ? and price >= ? and price <= ?";
        searchedLists = (List<Plot>)session.createQuery( query )
                .setInteger( 0, plotType )
                .setString( 1, plotSize )
                .setString( 2, min )
                .setString( 3, max ).list();
        return searchedLists;
    }

это мой общий запрос для всех 4 параметров, теперь мне нужно написать поисковый запрос, в котором я использую несколько необязательных параметров. Как сделать этот запрос с необязательными параметрами? любезно преобразовать мой запрос в запрос с динамически необязательными параметрами? Спасибо


person Ahmad    schedule 11.05.2016    source источник
comment
Возможно, вы сможете преобразовать его самостоятельно с помощью этой информации stackoverflow .com / questions / 12199433 /.   -  person RubioRic    schedule 11.05.2016
comment
я думаю, что это не то, о чем я прошу   -  person Ahmad    schedule 11.05.2016
comment
Уверены ли вы? Вы прочитали принятый ответ? В чем конкретно ваша проблема с этим ответом? Вам нужно создать CriteriaQuery, добавив только те предикаты, которые вам нужны. Вы можете получить список, вызвав метод getResultList, как только получите свой запрос.   -  person RubioRic    schedule 11.05.2016
comment
я не понял из этого, можете ли вы точно преобразовать мой запрос и опубликовать ответ?   -  person Ahmad    schedule 11.05.2016


Ответы (3)


Я сам преобразовал запрос вот так

Session session = sessionFactory.getCurrentSession();
        List<Plot> searchedLists = new ArrayList<Plot>();
        Map<String, Object> params = new HashMap<String,Object>();
        String hqlQuery = "from Plot where societyBlock.societyBlockId = :societyBlock";
        params.put( "societyBlock", societyId );
        if(plotType != null)
        {
            hqlQuery += " and type.typeId = :type";
            params.put( "type", plotType );
        }
        if(!plotSize.isEmpty() && plotSize != null && !plotSize.equals( "" ))
        {
            hqlQuery += " and size = :size";
            params.put( "size", plotSize );
        }
        if(min != null)
        {
            hqlQuery += " and price >= :pricemin";
            params.put( "pricemin", min );
        }
        if(max != null)
        {
            hqlQuery += " and price <= :pricemax";
            params.put( "pricemax", max );
        }
        Query query = session.createQuery( hqlQuery );

        for (String str : query.getNamedParameters())
        {
            query.setParameter( str, params.get( str ) );
        }
        searchedLists = (List<Plot>) query.list();
        System.out.println( searchedLists.size() );
        return searchedLists;
person Ahmad    schedule 11.05.2016

Другой вариант динамических запросов - использование Criteria API:

Criteria crit = session.createCriteria(Plot.class);
if (status != null) {
      crit.add(Restrictions.eq("status", status));
}
// other where clauses

Для вашего варианта из вопроса с динамическим построением критериев на основе ввода:

Criteria criteria = session.createCriteria(Plot.class);;
    if(type != null) {
        criteria.add(Restrictions.eq("type", type));
    }
    if(size != null) {
        criteria.add(Restrictions.eq("size", size));
    }
    if(min != null && max != null) {
        criteria.add(Restrictions.between("price", min, max));
    }
    List<Case> searchedLists  = criteria.list();
    return searchedLists;
person inigo skimmer    schedule 11.05.2016
comment
я не получил от этого, вы можете точно преобразовать мой запрос? - person Ahmad; 11.05.2016
comment
если какой-либо параметр имеет значение NULL, например, если поиск выполняется только с типом, тогда другие параметры равны нулю, поэтому он также может обрабатывать этот API критериев? если приходит только тип, то этот запрос будет выполняться только с типом? - person Ahmad; 11.05.2016
comment
а также показывает ошибку, потому что createCriteria не имеет метода списка, поэтому его нельзя сохранить в списке - person Ahmad; 11.05.2016
comment
Обновленный ответ. Вам нужно проверить, присутствуют ли некоторые входные параметры, и построить критерии на их основе. - person inigo skimmer; 11.05.2016
comment
Хорошо, теперь все выглядит нормально, но я конвертирую запрос сам, я просто поддерживаю вас, спасибо, я отправлю свой преобразованный запрос в качестве ответа - person Ahmad; 11.05.2016

Вы можете сделать что-то вроде показанного ниже:

    Map<String, Object> parameters= new HashMap<String,Object>();
    parameters.put("status", status);

    StringBuilder hql = "SELECT employee FROM Employee as employee where 1 = 1";
    if (status != null) {
      hql.append(" and employee.status in :status");
    }


    Query query = session.createQuery(hql.toString());


    for (String p : query.getNamedParameters()) {
      query.setParameter(p, parameters.get(p));
    }
person shankarsh15    schedule 11.05.2016
comment
я не получил от этого, вы можете точно преобразовать мой запрос? - person Ahmad; 11.05.2016