Java - executebatch не работает при вставке записей в db

Я пытаюсь вставить записи в свою таблицу в MYSQL после извлечения слов из файла и сохранения их в хэш-наборе.

Я попытался использовать executeBatch () для вставки в свою базу данных после получения 500 записей, но когда выполнение завершилось, я проверил свою таблицу, и запись не вставлена ​​вообще.

Примечание. Когда я использую ExecuteUpdate (), записи будут отображаться в моей таблице. Но не ExecuteBatch (), поскольку я хочу вставлять пакетно, а не по одному. Могу ли я узнать, что я сделал не так?

Код:

public void readDataBase(String path,String word) throws Exception {
        try {

            // Result set get the result of the SQL query

            int i=0;
            // This will load the MySQL driver, each DB has its own driver
            Class.forName("com.mysql.jdbc.Driver");
            // Setup the connection with the DB
            connect = DriverManager
                    .getConnection("jdbc:mysql://126.32.3.20/fulltext_ltat?"
                            + "user=root&password=root");

            // Statements allow to issue SQL queries to the database
          //  statement = connect.createStatement();
            System.out.print("Connected");
            // Result set get the result of the SQL query

            preparedStatement = connect
                    .prepareStatement("insert IGNORE into  fulltext_ltat.indextable values (default,?, ?) ");

            preparedStatement.setString(  1, path);
            preparedStatement.setString(2, word);
            preparedStatement.addBatch();
            i++;
           // preparedStatement.executeUpdate();

            if(i%500==0){
                preparedStatement.executeBatch();

            }




         preparedStatement.close();



            //  writeResultSet(resultSet);
        } catch (Exception e) {
            throw e;
        } finally {
            close();
        }

    }

Это мой цикл для вызова этого метода (слова - это просто массив, содержащий слова, которые будут вставлены в таблицу):

 for(int i = 1 ; i <= words.length - 1 ; i++ ) {

                    connection.readDataBase(path, words[i].toString());

                }

Мой основной метод:

public static void main(String[] args) throws Exception {

        StopWatch stopwatch = new StopWatch();
        stopwatch.start();



        File folder = new File("D:\\PDF1");
        File[] listOfFiles = folder.listFiles();

        for (File file : listOfFiles) {
            if (file.isFile()) {
                HashSet<String> uniqueWords = new HashSet<>();
                String path = "D:\\PDF1\\" + file.getName();
                try (PDDocument document = PDDocument.load(new File(path))) {

                    if (!document.isEncrypted()) {

                        PDFTextStripper tStripper = new PDFTextStripper();
                        String pdfFileInText = tStripper.getText(document);
                        String lines[] = pdfFileInText.split("\\r?\\n");
                        for (String line : lines) {
                            String[] words = line.split(" ");

                            for (String word : words) {
                                uniqueWords.add(word)
                                ;

                            }

                        }
                        // System.out.println(uniqueWords);

                    }
                } catch (IOException e) {
                    System.err.println("Exception while trying to read pdf document - " + e);
                }
                Object[] words = uniqueWords.toArray();



                MysqlAccessIndex connection = new MysqlAccessIndex();

                for(int i = 1 ; i <= words.length - 1 ; i++ ) {

                    connection.readDataBase(path, words[i].toString());

                }

                System.out.println("Completed");

            }
        }
0
0
1 915
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

где твоя петля. попробуй это

 connect = DriverManager
                .getConnection("jdbc:mysql://126.32.3.20/fulltext_ltat?"
                        + "user=root&password=root&rewriteBatchedStatements=true");

что это делает?

Daredevil 26.10.2018 06:43

Где ваш цикл, и ваше подготовленное заявление должно быть вне цикла

Orgil 26.10.2018 06:45

Если затем вы перемещаете соединение, подготовьте заявление о своей функции

Orgil 26.10.2018 06:48

значит как сделать?

Daredevil 26.10.2018 08:36
Ответ принят как подходящий

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

// define a collection of paths and words somewhere
List<String> paths = new ArrayList<>();
List<String> words = new ArrayList<>();

try {
    // presumably you only want to insert so many records
    int LIMIT = 10000;
    Class.forName("com.mysql.jdbc.Driver");
    connect = DriverManager
            .getConnection("jdbc:mysql://126.32.3.20/fulltext_ltat?"
                + "user=root&password=root");

    String sql = "INSERT IGNORE INTO fulltext_ltat.indextable VALUES (default, ?, ?);";
    preparedStatement = connect.prepareStatement(sql);

    for (int i=0; i < LIMIT; ++i) {
        preparedStatement.setString(1, paths.get(i));
        preparedStatement.setString(2, word.get(i));
        preparedStatement.addBatch();
        if (i % 500 == 0) {
            preparedStatement.executeBatch();
        }
    }

    // execute remaining batches
    preparedStatement.executeBatch();
}
catch (SQLException e) {
    e.printStackTrace();
}
finally {
    try {
        preparedStatement.close();
        connect.close();
    }
    catch (SQLException e) {
        e.printStackTrace();
    }
}

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

Какая часть моего кода состоит из бесконечного цикла? Если вы установите предел в 10 000, тогда, если мой хэш-набор содержит больше, чем предел, он не будет вставлен после 10 000, верно?

Daredevil 26.10.2018 06:49

Упс ... у вас нет цикла любой, что, вероятно, является причиной того, что пакеты не записываются в базу данных. Итак, вам нужен цикл где-то, но он должен быть там, где я выделил, и нет снаружи, где вы открываете свое соединение и готовите оператор вставки.

Tim Biegeleisen 26.10.2018 06:50

Ограничение - установить слова, которые можно вставить, до 10 000, я прав?

Daredevil 26.10.2018 06:56

Да, у меня есть до 10000 записей, которые вставляются партиями до 500 за раз (up to 500 ... последняя партия может быть не 500, в зависимости от выбранного вами лимита).

Tim Biegeleisen 26.10.2018 06:57

Я попробовал ваше решение и получил странный результат. У меня есть список повторяющихся слов (на самом деле более 1000), чего не должно быть. Это потому, что я вызываю метод из другого класса в другом цикле for? Если вы посмотрите мой отредактированный пост, я добавил некоторые изменения.

Daredevil 26.10.2018 06:59

Я предполагаю, что то, что произошло, было основано на вашем ответе, одно и то же слово будет вставлено в таблицу 10 000 раз, за ​​которым последует второе слово еще 10 000 раз. Думаю, если я установлю Limit = 1, это должно решить проблему, по крайней мере, так, как я ее вижу.

Daredevil 26.10.2018 07:02

Один из разумных подходов - просто передать список или коллекцию, или слова и пути. Затем обращайтесь к соответствующему элементу во время каждой итерации цикла q.v. мой обновленный ответ.

Tim Biegeleisen 26.10.2018 07:11

Ваше решение действительно работает, но, скажем, около 2000 слов, это занимает 2 минуты +, в то время как мое решение выше занимает более 30 секунд, единственное, что оно не записывает в таблицу db.

Daredevil 26.10.2018 07:13

Тогда это не будет значимым сравнительным сравнением. Значимое сравнение было бы, если бы ваша версия работала 30 секунд.

Tim Biegeleisen 26.10.2018 07:14

Я пропустил свои слова и пути в основном методе. Вы можете посмотреть мой отредактированный пост.

Daredevil 26.10.2018 07:16

Вопрос: Ваш текущий код работает? Все ли вставки в таблицу выполняются правильно? Если нет, то, наверное, дальше обсуждать не стоит.

Tim Biegeleisen 26.10.2018 07:17

Если все работает, то можно спросить, почему вы здесь задали вопрос?

Tim Biegeleisen 26.10.2018 07:18

Я имел в виду, что он работает, если я не реализовал метод ExecuteBatch, и когда я переключил свой способ сделать это с помощью этого метода ExecuteBatch, он не сработал, поэтому вопрос был размещен здесь. Ваш ответ определенно решил мой вопрос. Надеюсь теперь все ясно

Daredevil 26.10.2018 07:23

Если вы спрашиваете, почему executeBatch медленнее, я не знаю почему. Но имейте в виду, что тот факт, что ты медленнее в вашем Java-коде, не означает, что это увеличивает нагрузку на базу данных. Напротив, если не выполнять столь частые вызовы вставки, это может быть менее напряженным для базы данных, что может быть важно для приложения, которое часто обращается к своей БД.

Tim Biegeleisen 26.10.2018 07:24

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