powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Подготовка строки для SQL вставки
34 сообщений из 34, показаны все 2 страниц
Подготовка строки для SQL вставки
    #38580439
denis111111
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день
Нужно вставить в базу MySQL строку типа "1234\123\123'123232\n3434", как она есть, тобто экранировать \, \n, ' символы (все спец символы MySQL).
PrepareStatement мне не пойдет, так уж сложилось...
Может есть в JDBC есть готовая утилита для этого, или что-то другое?
...
Рейтинг: 0 / 0
Подготовка строки для SQL вставки
    #38580441
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
denis111111PrepareStatement мне не пойдет, так уж сложилось...
Really?
...
Рейтинг: 0 / 0
Подготовка строки для SQL вставки
    #38580444
denis111111
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlazkowiczReally?
ага
...
Рейтинг: 0 / 0
Подготовка строки для SQL вставки
    #38580451
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
так небывает
...
Рейтинг: 0 / 0
Подготовка строки для SQL вставки
    #38580476
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowiczтак небывает

Ошибка!
Правильно "не бывает" :)

Но вообще вдруг у человека обязательно использование API, которое принимает "строку запроса".
...
Рейтинг: 0 / 0
Подготовка строки для SQL вставки
    #38580482
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey Tomin,

Та я видел. Осечка. Был бы тут апдейт своих сообщений, исправил бы сразу.

Любой даже чужой API можно перелопатить. Единственный сценарий, это если надо целиком SQL запрос с параметрами куда-то передавать удаленно через XML или другой недодуманный протокол и удаленно же исполнять.
...
Рейтинг: 0 / 0
Подготовка строки для SQL вставки
    #38580506
denis111111
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ок, припустим PreparedStatement можно использовать, но как мне вставить с его помощью много записей?
...
Рейтинг: 0 / 0
Подготовка строки для SQL вставки
    #38580513
denis111111
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: java
1.
2.
3.
4.
5.
6.
7.
  PreparedStatement st = conn.prepareStatement("INSERT INTO `test`.`parent` (`name`) VALUES (?)");
            for (Parent p : list) {
                st.setString(1, p.getName());
                st.addBatch();
            }
            st.executeBatch();
            st.close();


Это правильный подход?

делал еще так:
Код: java
1.
2.
3.
4.
Statement st = conn.createStatement();
String query = createQuery(list);
st.executeUpdate(query);
st.close();


Результат времени вставок 200 записей:
Batch, size of records 100: 2422
Handle, size of records 100: 31
...
Рейтинг: 0 / 0
Подготовка строки для SQL вставки
    #38580775
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
denis111111
Код: java
1.
2.
3.
4.
5.
6.
7.
  PreparedStatement st = conn.prepareStatement("INSERT INTO `test`.`parent` (`name`) VALUES (?)");
            for (Parent p : list) {
                st.setString(1, p.getName());
                st.addBatch();
            }
            st.executeBatch();
            st.close();


Это правильный подход?


Нет. Вот пример правильного .
...
Рейтинг: 0 / 0
Подготовка строки для SQL вставки
    #38580802
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey Tomindenis111111
Код: java
1.
2.
3.
4.
5.
6.
7.
  PreparedStatement st = conn.prepareStatement("INSERT INTO `test`.`parent` (`name`) VALUES (?)");
            for (Parent p : list) {
                st.setString(1, p.getName());
                st.addBatch();
            }
            st.executeBatch();
            st.close();


Это правильный подход?


Нет. Вот пример правильного .

Блин. С утра не заметил. Что за БД, что тормозит на батче?
...
Рейтинг: 0 / 0
Подготовка строки для SQL вставки
    #38580804
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
denis111111
Код: java
1.
2.
3.
4.
5.
6.
7.
  PreparedStatement st = conn.prepareStatement("INSERT INTO `test`.`parent` (`name`) VALUES (?)");
            for (Parent p : list) {
                st.setString(1, p.getName());
                st.addBatch();
            }
            st.executeBatch();
            st.close();


Это правильный подход?


В общем- MySQL такая SQL, что везде надо напильник доставать.
По медленной вставке в гуле немало есть, например вот .
...
Рейтинг: 0 / 0
Подготовка строки для SQL вставки
    #38580882
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а кто мешает использовать такое?
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
StringBuilder sb= new StringBuilder();
sb.append("INSERT INTO `test`.`parent` (`name`) VALUES ");
for (Parent p : list) {
                ab.append("('").append( p.getName()).append("'),");
            }
sb.delete(sb.length() - 1, sb.length());

PreparedStatement st = conn.prepareStatement(sb.toString());
st.executeQuery();
...
Рейтинг: 0 / 0
Подготовка строки для SQL вставки
    #38580909
0FD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
denis111111,

Может поможет, не знаю работает ли.

http://www.java2s.com/Code/Java/Data-Type/UnescapeanyMySQLescapesequences.htm
...
Рейтинг: 0 / 0
Подготовка строки для SQL вставки
    #38580922
0FD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
0FD,

В догонку, есть рекомендации
http://stackoverflow.com/questions/2993251/jdbc-batch-insert-performance
...
Рейтинг: 0 / 0
Подготовка строки для SQL вставки
    #38580938
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
из последней ссылки

You can insert multiple rows with one insert statement, doing a few thousands at a time can greatly speed things up, that is, instead of
doing e.g. 3 inserts of the form INSERT INTO tbl_name (a,b,c) VALUES(1,2,3); , you do INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),
(1,2,3),(1,2,3); (It might be JDBC .addBatch() does similar optimization now - though the mysql addBatch used to be entierly un-optimized
and just issuing individual queries anyhow - I don't know if that's still the case with recent drivers)

If you really need speed, load your data from a comma separated file with LOAD DATA INFILE , we get around 7-8 times speedup doing that
vs doing tens of millions of inserts.
...
Рейтинг: 0 / 0
Подготовка строки для SQL вставки
    #38581005
denis111111
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо за советы
Я так понял что MySQL драйвер не делает multiple insert, я тестировал скорость и вот что вышло:

Handle, size of records 1000: 125 -- вставка происходит одним запросом типа INSERT INTO `parent` (`name`) VALUES (1), (1), (1)...
Batch, size of records 1000: 26985 -- вставка через батч
Simple, size of records 1000: 29218 -- вставка каждой записи оддельно

0FD
На жаль это Unescape any MySQL escape sequences. не подходит , например из 'В\яче\слав' зделает 'Вячеслав', а должно быть 'В\\яче\\слав'
...
Рейтинг: 0 / 0
Подготовка строки для SQL вставки
    #38581038
0FD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
denis111111,

Ну а это пробовали?

I had a similar performance issue with mysql and solved it by setting the useServerPrepStmts and the rewriteBatchedStatements properties in the connection url.

пишут скорость увеличилась от 3 до 30 раз
...
Рейтинг: 0 / 0
Подготовка строки для SQL вставки
    #38581052
denis111111
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
0FD,
Вот результат если прописать ?useServerPrepStmts=false&rewriteBatchedStatements=true:
Handle, size of records 100: 47
Batch, size of records 100: 47
Simple, size of records 100: 2281
Это как раз то что нужно, спасибо)
...
Рейтинг: 0 / 0
Подготовка строки для SQL вставки
    #38581055
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Интересно с MariaDB такая же лажа?
...
Рейтинг: 0 / 0
Подготовка строки для SQL вставки
    #38581086
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
как ни крути, а
одним запросом типа INSERT INTO `parent` (`name`) VALUES (1), (1), (1)...
будет быстрее, потому как все разделено, т.е. формирование sql строки через StringBuilder самое быстрое из возможных и
выполнение полностью отдается серверу mysql.
а Batch это дополнительная прослойка, требующая время.

ну а чтоб экранировать можно воспользоваться регулярными выражениям.
...
Рейтинг: 0 / 0
Подготовка строки для SQL вставки
    #38581135
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
denis1111110FD,
Вот результат если прописать ?useServerPrepStmts=false&rewriteBatchedStatements=true:
Handle, size of records 100: 47
Batch, size of records 100: 47
Simple, size of records 100: 2281
Это как раз то что нужно, спасибо)

Не зря я не люблю мускл :)

Я б попробовал

insert into vvv (...) values (?),(?),(?)

А потом навставлять параметров. Если ничего не треснет- может получится интересно.
...
Рейтинг: 0 / 0
Подготовка строки для SQL вставки
    #38581158
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а чем отличается
insert into vvv (...) values (?),(?),(?)
от
одним запросом типа INSERT INTO `parent` (`name`) VALUES (1), (1), (1)...

дополнительной прослойкой?
второй вариант я даже реализовал в хранимке и выполнял с помощью PREPARE
летает на ура.
...
Рейтинг: 0 / 0
Подготовка строки для SQL вставки
    #38581175
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вадяа чем отличается
insert into vvv (...) values (?),(?),(?)
от
одним запросом типа INSERT INTO `parent` (`name`) VALUES (1), (1), (1)...

Тем, что во тором варианте можно поиметь проблемы с sql-инъекциями, намеренными или нет
...
Рейтинг: 0 / 0
Подготовка строки для SQL вставки
    #38581183
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а впервом, кто мешает вместо вопроса инъекцию вставить?
...
Рейтинг: 0 / 0
Подготовка строки для SQL вставки
    #38581186
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вадяа чем отличается
insert into vvv (...) values (?),(?),(?)
от
одним запросом типа INSERT INTO `parent` (`name`) VALUES (1), (1), (1)...

дополнительной прослойкой?

Собственно второй вариант не подходит автору, т.к. у него в строке всякие чудеса.
...
Рейтинг: 0 / 0
Подготовка строки для SQL вставки
    #38581200
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey Tominвадяа чем отличается
insert into vvv (...) values (?),(?),(?)
от
одним запросом типа INSERT INTO `parent` (`name`) VALUES (1), (1), (1)...

дополнительной прослойкой?

Собственно второй вариант не подходит автору, т.к. у него в строке всякие чудеса.

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

с точки зрения безопасности оба метода раскрывают структуру таблицы, в случае декомпиляции кода, это важно если данный код не серверный. поэтому лучше использовать хранимки, и там проверять на возможные инъекции.
...
Рейтинг: 0 / 0
Подготовка строки для SQL вставки
    #38581288
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вадяа впервом, кто мешает вместо вопроса инъекцию вставить?

А как?
...
Рейтинг: 0 / 0
Подготовка строки для SQL вставки
    #38581293
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вадяBatch это дополнительная прослойка, требующая время.

В нормальных БД это не прослойка, а фича сервера. В мускуле и прослойка? Тогда это ещё один повод забыть о нём.

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

И постоянно трястись, что что-то не учёл. Сколько серверов взломано из-за неучтённого изврата хакера- не счесть.
...
Рейтинг: 0 / 0
Подготовка строки для SQL вставки
    #38581447
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey Tominвадяа впервом, кто мешает вместо вопроса инъекцию вставить?

А как?


так же как и во втором случае
в обоих случаях данные вставляются из одго источника(тут за небольшим исключением, что в первом случае выполняется по одному значению (для ускорения можно привести и к вставке нескольких))

Код: java
1.
2.
3.
4.
 for (Parent p : list) {
                st.setString(1, p.getName());
                st.addBatch();
            }




Код: java
1.
2.
3.
for (Parent p : list) {
                ab.append("('").append( p.getName()).append("'),");
            }



в итоге сервер mysql выполнит один и тот же код



авторВ нормальных БД это не прослойка, а фича сервера. В мускуле и прослойка? Тогда это ещё один повод забыть о нём.

это прослойка не у БД, прослойка позволяющая преообразовать обращение к БД другим методом, для кого-то более наглядным
такая запись
insert into vvv (...) values (?),(?),(?) и т.д.
более читабельна, чем
sb.append("INSERT INTO `test`.`parent` (`name`) VALUES ");
for (Parent p : list) {
ab.append("('").append( p.getName()).append("'),");
}
sb.delete(sb.length() - 1, sb.length());

я ни где не слышал что batch проверяет на инъекции. а если есть такая проверка - то это еще один дополнительный тормоз.
боишься инъекций - проверяй вносимые данные на соответствие твоим хранимым данным(с большей долей вероятности можно сказать что у большинства данных нет ключевых слов базыданных)


авторИ постоянно трястись, что что-то не учёл. Сколько серверов взломано из-за неучтённого изврата хакера- не счесть.

это в любом случае не избежать, если буде поставлена такая цель
как пример правильная проверка мыла 15595681
...
Рейтинг: 0 / 0
Подготовка строки для SQL вставки
    #38581554
avp.mk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Попробовал на оракле (10g XE)

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
10 000 записей
batch    :   0,708014 сек
non-batch:   2,480134 сек
text     :   5,355829 сек
(С включенным AutoCommit'ом всё медленнее и text отрабатывает быстрее non-batch, но оба сильно отстают от batch.)

1 000 000 записей
batch    :  64,167224 сек
non-batch: 265,693908 сек
text     : PLS-00123: program too large (Diana nodes) или java.lang.OutOfMemoryError




Может быть вариант с текстом можно было сделать лучше, но все равно останутся проблемы:
1. Нужно собрать строку больших размеров. (а чтобы это сделать нужно позволить JVM съесть много памяти)
2. Sql инъекции & экранирование символов.
3. Приседания c локалями (разделителями целой и дробной части). Чтобы внезапно не получить заместо пяти тысяч (5001,35) пол миллиона (500135).
4. Вставка дат\бинарных данных (первое представляю как сделать, второе даже представлять не хочу..)


Код
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
package testvelosiped;

import java.sql.SQLException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Random;
import static testvelosiped.Db.getConnection;
import static testvelosiped.Db.prepareStatement;
import static java.lang.System.*;

public class TestVelosiped {

    private static final Random RANDOMIZER = new Random();

    private static final int
//            COUNT = 10_000;
            COUNT = 1_000_000;
    
    private static String modelName = "Какой-нибудь текст";
    private static double height = 2.5, length = 3.2, width = 86, weight = 5.25;

    public static void main(String[] args) throws SQLException {
        Connection connection = getConnection();
        connection.setAutoCommit(false);
        long time = nanoTime();
//        testBatch();
        testNonBatch();
//        testText();
        connection.commit();
        time = nanoTime() - time;

        out.printf("Время %f сек\n", time / 1e9);
    }

    private static void testNonBatch() throws SQLException {
        PreparedStatement psCreate = prepareStatement(
                "INSERT INTO your_schema_name.velosipeds (model_name, height, length, width, weight) " +
                "VALUES (?, ?, ?, ?, ?)");

        for (int i = 0; i < COUNT; ++i) {
            psCreate.setString(1, modelName);
            psCreate.setDouble(2, height);
            psCreate.setDouble(3, length);
            psCreate.setDouble(4, width);
//            psCreate.setDouble(5, weight);
            psCreate.setDouble(5, RANDOMIZER.nextInt(100));
            psCreate.executeUpdate();
        }
    }

    private static void testBatch() throws SQLException {
        PreparedStatement psCreate = prepareStatement(
                "INSERT INTO your_schema_name.velosipeds (model_name, height, length, width, weight) " +
                "VALUES (?, ?, ?, ?, ?)");

        for (int i = 0; i < COUNT; ++i) {
            psCreate.setString(1, modelName);
            psCreate.setDouble(2, height);
            psCreate.setDouble(3, length);
            psCreate.setDouble(4, width);
//            psCreate.setDouble(5, weight);
            psCreate.setDouble(5, RANDOMIZER.nextInt(100));
            psCreate.addBatch();
        }

        psCreate.executeBatch();
    }

    private static void testText() throws SQLException {
        StringBuilder sb = new StringBuilder("BEGIN\n");

        for (int i = 0; i < COUNT; ++i) {
            sb
                    .append("INSERT INTO your_schema_name.velosipeds (model_name, height, length, width, weight) VALUES ('")
                    .append(modelName).append("',")
                    .append(height).append(",")
                    .append(length).append(",")
                    .append(width).append(",")
//                    .append(weight)
                    .append(RANDOMIZER.nextInt(100))
                    .append(");\n");
        }

        sb.append("END;");
        getConnection().prepareCall(sb.toString()).execute();
    }
}


Класс Db (если нужен) тут
...
Рейтинг: 0 / 0
Подготовка строки для SQL вставки
    #38581592
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вадяAlexey Tominпропущено...
А как?
так же как и во втором случаев обоих случаях данные вставляются из одго источника(тут за небольшим исключением, что в первом случае выполняется по одному значению (для ускорения можно привести и к вставке нескольких))
пропущено...
в итоге сервер mysql выполнит один и тот же код


Понял. Т.е. MySQL, в отличии от Oracle, firebird, postgresql и т.д. и т.п. не умеет делать ни batch-update, ни predaredStatement и драйвер это тупо эмулирует. Т.е. MySQL использовать нельзя никогда и нигде.

А автору- да, нужно извращаться с регулярными выражениями и верить, что его не сломают.


вадяя ни где не слышал что batch проверяет на инъекции. а если есть такая проверка - то это еще один дополнительный тормоз.
боишься инъекций - проверяй вносимые данные на соответствие твоим хранимым данным(с большей долей вероятности можно сказать что у большинства данных нет ключевых слов базыданных)

В нормальных серверах проверка не нужна. Т.к. подстановка параметров в запрос идёт после того, как сервер распарсил текст, превратил его в дерево, построил план запроса. Т.е. в текст можно вставить хоть что- проблем не будет НИКАКИХ.
При этом даже без batch-update prepared будет быстрее, т.к. парсер найдёт запрос в кэше и просто возьмёт готовое дерево.
...
Рейтинг: 0 / 0
Подготовка строки для SQL вставки
    #38581661
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2avp.mk
я б не стал таким образом вставлять более 100 строк
для этого существует вставка из файла LOAD DATA

авторт.е. MySQL использовать нельзя никогда и нигде.

категоричность не есть правильность....
у mysql есть своя ниша и довольно большая

насчет predaredStatement в mysql -
http://dev.mysql.com/doc/refman/5.0/en/sql-syntax-prepared-statements.html
оно есть :)
...
Рейтинг: 0 / 0
Подготовка строки для SQL вставки
    #38581667
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Подготовка строки для SQL вставки
    #38581670
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
34 сообщений из 34, показаны все 2 страниц
Форумы / Java [игнор отключен] [закрыт для гостей] / Подготовка строки для SQL вставки
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]