Разобрать строку запроса SQL, чтобы получить карту значений

У меня есть Java-проект, в котором PreparedStatements не используются ни в одном SQL-запросе. Теперь я хочу реализовать PreparedStatements для всех этих запросов. Вместо того, чтобы изменять каждый запрос, помещая "?" , Я хочу написать функцию, которая принимает строку запроса SQL, которая анализирует ее и возвращает карту значений различных предложений SQL.

public class SQLParser {

    public static void main(String args[]) {

    String sqlString = "select * from table t where columnA = 'hello' and columnB = 'hai'";
    Map<Integer,String> values = new HashMap<>();
    values = parseQuery(sqlString);
    System.out.println(values);   // prints  { {1,'hello'} , {2,'hai'} }
    }

    private static Map<Integer,String> parseQuery(String sqlString) {
        Map<Integer,String> values = new HashMap<>();
        //
        //  ????  I want this function 
        //
        return values;
        
    }

}

Несколько примеров

sqlString: выберите * из таблицы t, где columnA = 'hello' AND columnB = 'hai'
вывод: {{1, 'hello'}, {2, 'hai'}}

sqlString: выберите * из таблицы t, где columnA IN ('hello', 'hai')
вывод: {{1, 'hello'}, {2, 'hai'}}

sqlString: выберите * из таблицы t, где столбец A> 17 И столбец B МЕЖДУ 10 И 20;
вывод: {{1, '17 '}, {2,' 10 '}, {3,' 20 '}}

По сути, он должен поддерживать все возможные предложения и их комбинации.

Если ключи вашей карты представляют собой инкрементные числа, разве списка будет недостаточно?

Federico klez Culloca 30.03.2021 13:30

В любом случае, вы в основном спрашиваете, как написать синтаксический анализатор для SQL (какой диалект SQL, кстати?), Что, если вы спросите меня, кажется немалым подвигом. Я не уверен, что он подходит для ответа StackOverflow.

Federico klez Culloca 30.03.2021 13:32

В любом случае вам придется изменить код для каждого запроса, использовать ли ваш анализатор / подготовитель волшебных операторов или использовать PreparedStatement напрямую. Не могли бы вы разработать этот волшебный анализатор / средство подготовки, а затем модифицировать каждый запрос для его использования за меньшее время, чем просто переписать каждый запрос как PreparedStatement? О скольких запросах идет речь?

Kevin Anderson 30.03.2021 14:02

Я думаю, вы здесь что-то упускаете. Смысл использования PreparedStatement - избегать SQL-инъекций. Но если вы сначала создадите свой SQL как строку из ваших параметров, инъекция может произойти в этот момент, и ваш синтаксический анализатор с радостью проанализирует вредоносный оператор SQL.

vanje 30.03.2021 20:25
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
4
20
1

Ответы 1

Правильный способ реализовать это будет создание парсера SQL. Это огромная задача. Если вы решите пойти этим путем, вы можете взглянуть на мой парсер (Scala), хотя он еще даже не близок к завершению.

Альтернативный подход - создать регулярное выражение для захвата всего литерала. Для этого нужен только сканер, что проще.

Другие вопросы по теме