Построение запросов Hibernate на основе условий - PullRequest
1 голос
/ 18 ноября 2011

У меня есть форма, где пользователь может выбрать критерии поиска.

Критерии говорят:

Product Name: Input field
Name Option: Radio button group - begins with (default selected)/ is/ contains
Country: dropdown of country
Status: All, Active, Blocked
Type: All, One, Two, Three

Обязательно только название продукта. Другие выпадающие меню не являются обязательными.

Так что, если страна не указана, я должен найти товары для всех стран. Если active не указан, я должен найти как активные, так и заблокированные продукты. Если Тип не указан, я должен вернуть все продукты трех типов.

Я создаю запрос гибернации, как показано ниже:

String productName = searchCriteria.getValue("productName");
String productNameCriteria = searchCriteria.getValue("productNameCriteria");
String country = searchCriteria.getValue("country");
String status = searchCriteria.getValue("status");
String type = searchCriteria.getValue("type");

Query prodQuery = null;
String prodSql = "select count(*) from Product p where";

// is
if (productNameCriteria.equalsIgnoreCase("IS")){
            prodSql += "p.productName = '"+productName+"'";
        }

// begins with
else if (productNameCriteria.equalsIgnoreCase("BEGINS WITH")){
            prodSql += "p.productName = '"+productName+"%'";
        }

// contains
else (productNameCriteria.equalsIgnoreCase("BEGINS WITH")){
            prodSql += "p.productName = '%"+productName+"%'";

        }

if(!country.equalsIgnoreCase("0")){
         prodSql += " and p.country = '"+country+"'";
     }

if(!status.equalsIgnoreCase("ALL")){
      if(status.equalsIgnoreCase("active"))
          prodSql += " and p.status = 'active'";

      else
          prodSql += " and p.status = 'blocked'";
 }

 if(!type.equalsIgnoreCase("ALL")){
      if(type.equalsIgnoreCase("one"))
          prodSql += " and p.type = 'one'";

      else if(type.equalsIgnoreCase("two"))
          prodSql += " and p.type = 'two'";

      else 
         prodSql += " and p.type = 'three'";
}

prodQuery = this.em.createQuery(prodSql);
List<Object[]> results = prodQuery.getResultList();

Я правильно строю запросы? Или есть какой-нибудь другой эффективный метод ???

Спасибо за чтение !!

Ответы [ 2 ]

4 голосов
/ 18 ноября 2011

Попробуйте посмотреть Критерий запроса

Criteria crit = sess.createCriteria(Product.class);
if (productNameCriteria.equalsIgnoreCase("IS"))
    crit.add( Restrictions.eq("productName", productName);
else if (productNameCriteria.equalsIgnoreCase("BEGINS WITH"))
    crit.add( Restrictions.like("productName", productName + "%")
// etc

Если вам абсолютно необходимо создать строковый запрос, вы должны использовать StringBuilder

StringBuilder sb = new StringBuilder();
sb.append("select count(*) from Product p where ");
if (productNameCriteria.equalsIgnoreCase("IS"))
    sb.append("p.productName = '").append(productName).append("'");
// etc
String query = sb.toString();

Использование StringBuilder уменьшает количество экземпляров, создаваемых во время выполнения.

Вы также можете изучить использование параметров запроса, которые могут снизить сложность запроса, хотя я не знаю, каковы эффекты производительности запроса во время выполнения.

"select count(*) from Product p where p.productName = :productName"
"select count(*) from Product p where p.productName = ?"

Затем вы можете использовать Query#setParameter (или один из других вариантов, например setString), чтобы определить значения в запросе. Это также намного лучший способ построения запроса, потому что он будет автоматически управлять цитированием и экранированием значений, которые вы получаете от пользовательского интерфейса. Использовать параметры запроса, а не конкатенацию строк , независимо от того, как вы строите строку запроса.

2 голосов
/ 18 ноября 2011

Да. Это будет работать, если вы построите запрос динамически таким образом. Но код станет утомительным и шумным, поскольку он включает в себя манипулирование строкой условия where.

Для этого варианта использования запроса, который представляет собой поиск, который позволяет пользователям указывать диапазон различных значений свойств, которые должны соответствовать возвращаемому набору результатов, используя Запрос по примеру (QBE) более эффективный и элегантный.

Идея QBE состоит в том, что вы предоставляете экземпляр запрашиваемого класса с некоторыми инициализированными свойствами, и запрос возвращает записи с соответствующими значениями свойств.


Ссылка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...