Можем ли мы заменить часть строки в Java с символом в начале и в конце идентифицировать? - PullRequest
0 голосов
/ 23 февраля 2019

У меня есть строка SELECT *FROM USERS WHERE ID = '@userid@' AND ROLE = '@role@' Теперь я должен заменить любую строку между @ ... @ действительным значением.

Ожидаемый результат SELECT *FROM USERS WHERE ID = '4' AND ROLE = 'Admin'

Эта замена произойдет из метода, я написал эту логику

public String replaceQueryKeyWithValueFromKeyValues(String query, int reportId) {
    try {
        REPMReportDao repmReportDao = new REPMReportDao();
        int Start = 0;
        int end;
        if (query.contains("@")) {
            boolean specialSymbolFound = false;
            for (int i = 0; i < query.length(); i++) {
                if (query.charAt(i) == '@') {
                    if (!specialSymbolFound) {
                        Start = i + 1;
                        specialSymbolFound = true;
                    } else {
                        specialSymbolFound = false;
                        end = i;
                        query = query.replace(query.substring(Start - 1, end + 1), repmReportDao.getReportManagerKeyValue(query.substring(Start - 1, end + 1).replaceAll("@", ""), reportId));

                    }
                }
            }
            return query;
        } else {
            return query;
        }

    } catch (Exception e) {
        logger.log(Priority.ERROR, e.getMessage());
        return e.getMessage();
    }
}

Он работает нормально, но в случае, если одинСимвол '@' существует вместо начала и конца, он потерпит неудачу.Например:

SELECT  *FROM USERS WHERE emailid = 'xyz@gmail.com' AND ROLE = '@role@'

Здесь он должен заменить единственную роль '@ role @' и оставить сообщение электронной почты без изменений.

Ожидаемый результат => SELECT *FROM USERS WHERE emailid = 'xyz@gmail.com' AND ROLE = 'Admin'

Ответы [ 2 ]

0 голосов
/ 23 февраля 2019

Полный пример с проверенными данными, возвращаемыми getReportManagerKeyValue:

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StackOverflow54842971 {

    private static Map<String, String> map;

    public static void main(String[] args) {
        // preparing test data
        map = new HashMap<>();
        map.put("role", "Admin");
        map.put("userid", "666");

        // original query string
        String query = "SELECT * FROM USERS WHERE ID = '@userid@' AND emailid = 'xyz@gmail.com' AND ROLE = '@role@' ";

        // regular expression to match everything between '@ and @' with capture group
        // omitting single quotes
        Pattern p = Pattern.compile("'(@[^@]*@)'");
        Matcher m = p.matcher(query);
        while (m.find()) {
            // every match will be replaced with value from getReportManagerKeyValue
            query = query.replace(m.group(1), getReportManagerKeyValue(m.group(1).replaceAll("@", "")));
        }
        System.out.println(query);
    }

    // you won't need this function
    private static String getReportManagerKeyValue(String key) {
        System.out.println("getting key " + key);
        if (!map.containsKey(key)) {
            return "'null'";
        }
        return map.get(key);
    }
}

0 голосов
/ 23 февраля 2019

Считается очень плохой практикой использовать подстановку строк для генерации запросов к базе данных, потому что вы оставляете свой код открытым для атак SQL-инъекций.Я не могу сказать из небольшого примера кода, который вы предоставили, но подавляющее большинство крупномасштабных проектов Java использует Spring Framework , который позволяет вам использовать либо JdbcTemplate , либо(мои предпочтения) NamedParameterJdbcTemplate .Оба позволят вам заменить переменные безопасным способом.

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