Java / JDBC - лучший метод поиска по нескольким параметрам - PullRequest
0 голосов
/ 01 февраля 2011

Я использую следующий код для генерации результатов поиска из реляционной БД в зависимости от нескольких (необязательных) параметров поиска из веб-клиента.

В настоящее время я использую «java.sql.Statement» для достижения функциональности, но мне нужно то же самое, чтобы достичь с помощью «java.sql.PreparedStatement», чтобы предотвратить инъекции SQL.

Дайте мне знать, как лучше изменить код


например.

Вводимые пользователем данные из веб-клиента.

  • param1 - необязательно
  • param2 - необязательно
  • dateParamFr - Необязательно
  • dateParamTo - опционально

Псевдокод шаблонов SQL в зависимости от параметров поиска:

IF (WITHOUT ANY SEARCH PARAMETER){
    SELECT * FROM TEST_TABLE;
}
ELSE IF(WITH param1){
    SELECT * FROM TEST_TABLE WHERE COLUMN1= param1;
}
ELSE IF(WITH param1 & param2){
    SELECT * FROM TEST_TABLE WHERE COLUMN1= param1 AND  COLUMN2= param2
}
SO ON
………

Ниже приведен фрагмент кода Java в моем EJB

.
    /* 
        NOTE : Hashtable pSearchParam is a method parameter
    */

    Connection  cnBOP           = null;
    Statement stmt              = null;
    StringBuffer sb             = new StringBuffer("");         

    try {
        cnBOP   = jdbcBOP.getConnection(); // DataSource jdbcBOP
        stmt    = cnBOP.createStatement();

        /* ######################## SQL BODY ######################################*/
        sb.append("SELECT COLUMN1, COLUMN2, DATE_COLUMN ");
        sb.append("FROM TEST_TABLE ");

        /* ######################## SQL WHERE CLAUSE ##############################*/
        if(pSearchParam.size()>=1){
            sb.append("WHERE ");
            Enumeration e = pSearchParam.keys();
            int count =0;

            while(e.hasMoreElements()){
                if (count >=1) sb.append("AND ");

                String sKey = (String) e.nextElement();

                if (sKey.equals("param1"))              sb.append ("COLUMN1 ='"+pSearchParam.get(sKey)+"' ");
                else if (sKey.equals("param1"))         sb.append ("COLUMN2 ='"+pSearchParam.get(sKey)+"' ");                   
                else if (sKey.equals("dateParamFr"))    sb.append ("DATE_COLUMN >= TO_DATE('"+pSearchParam.get(sKey)+" 00:00:00','DD/MM/YYYY HH24:MI:SS') ");
                else if (sKey.equals("dateParamTo"))    sb.append ("DATE_COLUMN <= TO_DATE('"+pSearchParam.get(sKey)+" 23:59:59','DD/MM/YYYY HH24:MI:SS') ");

                count ++;
            }
        }
        /* ######################## SQL ORDER BY CLAUSE ############################*/
        sb.append("ORDER BY DATE_COLUMN DESC");

        ResultSet rs = stmt.executeQuery(sb.toString());

Ответы [ 4 ]

4 голосов
/ 01 февраля 2011

вместо

sb.append ("COLUMN1 ='"+pSearchParam.get("param1")+"' ");

Вам придется сделать

sb.append ("COLUMN1 = ? ");

и затем после создания вы делаете

stmt.setString(1, pSearchParam.get("param1"));

Это только для первого параметра, вам нужно сделать это для всех операторов и перечислить индекс в

setString(int index, String param);

Обратите внимание, что вам нужно будет использовать другие методы для int, long, Date ... и т.д.

1 голос
/ 01 февраля 2011

В зависимости от вашей базы данных вы можете использовать функции SQL, такие как

isnull(value,valueIfNull) 

например в MSSQL

select * from Order where storeId = isnull(?,storeId)

следующий в вас код Java

preparedStatement.setNull(1,java.sql.Types.INTEGER)

если вам нужно пропустить этот параметр из фильтра или,

preparedStatement.setInt(1,20)

если вам нужно найти все заказы с storeId = 20

0 голосов
/ 01 февраля 2011

Вы используете Hibernate?Тогда вы можете использовать критерий API .Еще для не спящего режима вы можете взглянуть на инструмент SqlBuilder для генерации SQL на основе условий.

Также вы должны использовать маркеры "?"вместо фактических значений.

Так что этот запрос должен быть таким.

SELECT * FROM TEST_TABLE WHERE COLUMN1= ?;

Затем можно использовать PreparedStatements , чтобы установить значения для этого столбца.Вводное руководство по использованию PreparedStatement: здесь .

0 голосов
/ 01 февраля 2011

Это действительно похоже на работу для запросов Hibernate Criteria ...

Критерии - это упрощенный API для извлечения сущностей путем составления Критерий объектов. Это очень удобный подход для функциональности как «поиск» экранов, где есть переменное количество условий, которые будут помещается на набор результатов.

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