Java SQL Server: пакетная обработка

В этом руководстве вы узнаете, как выполнять пакетные операции в SQL Server с использованием JDBC API.

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

Введение в пакетные операции

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

Ниже описаны этапы пакетной обработки:

  • Сначала откройте новое подключение к базе данных.
  • Во-вторых, создайте новый объект PreparedStatement, который принимает оператор SQL, включая INSERT, UPDATE и DELETE.
  • В-третьих, задайте параметры для оператора, вызвав методы set* объекта PreparedStatement.
  • В-четвертых, вызовите метод addBatch() объекта PreparedStatement, чтобы добавить оператор в пакет.
  • В-пятых, вызовите executeBatch() для выполнения операторов как пакета.
  • Наконец, закройте операторы и соединение с базой данных.

Если вы используете оператор try-with-resources, вам не нужно вручную закрывать операторы и соединение с базой данных.

Пример пакетной операции JDBC

Мы покажем, как считывать данные об авторах из файла authors.csv и вставлять их в таблицу Authors.

1) Чтение данных из CSV-файла

Шаг 1. Загрузите файл author.csv:

Нажмите здесь, чтобы загрузить файл authors.csv

Файл authors.csv содержит заголовок и 30 строк данных, каждая из которых представляет собой запись, в которой хранится информация об авторе, включая имя, фамилию и дату рождения.

Шаг 2. Скопируйте файл authors.csv в каталог на вашем компьютере, например D:\csv\authors.csv.

Шаг 3. Создайте класс CSV, который имеет методы для чтения данных из файла authors.csv, анализа каждой строки и возврата списка объектов Author:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.stream.Collectors;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class CSV {
    public static List read(String filename) throws IOException {
        return Files.lines(Paths.get(filename))
                .skip(1) // Skip the first line(header)
                .map(CSV::parseLineToAuthor)
                .collect(Collectors.toList());
    }
    private static Author parseLineToAuthor(String line) {
        String[] fields = line.split(",");
        if(fields.length < 3) {
            throw new IllegalArgumentException("Invalid line: " + line);
        }
        String firstName = fields[0].trim();
        String lastName = fields[1].trim();
        LocalDate birthDate = LocalDate.parse(fields[2].trim(), DateTimeFormatter.ISO_LOCAL_DATE);
        return new Author(firstName, lastName, birthDate);
    }
}

2) Выполнение пакетных операций

Шаг 1. Добавьте новый метод insertMany() в класс AuthorDB:

public void insertMany(List  authors) throws DBException {
  if(authors == null || authors.isEmpty()) {
    return;
  }
  var sql = "INSERT INTO Authors(FirstName, LastName, BirthDate) VALUES(?, ?, ?)";
  try(var statement = connection.prepareStatement(sql)) {
    for(Author author: authors) {
      // Bind values
      statement.setString(1, author.getFirstName());
      statement.setString(2, author.getLastName());
      statement.setDate(3, Date.valueOf(author.getBirthDate()));
      // Add to batch
      statement.addBatch();
    }
    // Execute batch
    statement.executeBatch();
  } catch(SQLException e) {
    throw new DBException(e.getMessage());
  }
}

Как это работает.

Сначала определите новый метод insertMany, который принимает список объектов Author:

public void insertMany(List authors) {

Во-вторых, немедленно верните значение, если список авторов пуст или равен нулю:

if(authors == null || authors.isEmpty()) {
  return;
}

В-третьих, создайте оператор SQL для вставки новой строки в таблицу Authors:

var sql = "INSERT INTO Authors(FirstName, LastName, BirthDate) VALUES(?, ?, ?)";

В-четвертых, создайте объект PreparedStatement:

try(var statement = connection.prepareStatement(sql))

В-пятых, выполните итерацию по списку авторов, привяжите значения к запросу и добавьте PreparedStatement в пакет.

for(Author author: authors) {
  // Bind values
  statement.setString(1, author.getFirstName());
  statement.setString(2, author.getLastName());
  statement.setDate(3, Date.valueOf(author.getBirthDate()));
  // Add to batch
  statement.addBatch();
}

Наконец, создайте новое исключение DBException, если во время пакетной обработки возникнет ошибка:

throw new DBException(e.getMessage());

Шаг 2. Измените класс Main для чтения данных из файла authors.csv и импорта их в таблицу Authors:

import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
public class Main {
    public static void main(String[] args) {
        // Read data from authors.csv file
        List authors;
        try {
            authors = CSV.read("D:/csv/authors.csv");
        } catch(IOException e) {
            System.err.println(e.getMessage());
            return;
        }
        // Connect to the SQL Server
        try(var connection = SQLServerConnection.connect()) {
            var authorDB = new AuthorDB(connection);
            // insert authors
            authorDB.insertMany(authors);
        } catch(SQLException | DBException e) {
            System.err.println(e.getMessage());
        }
    }
}

Как это работает.

Сначала считайте данные из CSV-файла, вызвав метод read() класса CSV:

List  authors;
try {
  authors = CSV.read("D:/csv/authors.csv");
} catch(IOException e) {
  System.err.println(e.getMessage());
  return;
}

Во-вторых, подключитесь к SQL Server и вызовите метод insertMany() объекта AuthorDB, чтобы вставить список авторов в базу данных:

// Connect to the SQL Server
try(var connection = SQLServerConnection.connect()) {
  var authorDB = new AuthorDB(connection);
  // insert authors
  authorDB.insertMany(authors);
} catch(SQLException | DBException e) {
  System.err.println(e.getMessage());
}

Шаг 3. Запустите программу Java.

3) Проверка пакетных операций

Шаг 1. Запустите SQL Server Management Studio(SSMS) и подключитесь к SQL Server.

Шаг 2. Выполните следующий запрос для извлечения данных из таблицы Authors:

SELECT * FROM Authors;

Выход:

пакетная операция java sql server

Вывод показывает, что программа успешно вставила еще 30 строк в таблицу Authors.

Загрузите исходный код проекта

Загрузите исходный код проекта

Краткое содержание

  • Используйте метод addBatch() для добавления подготовленного оператора в пакет.
  • Вызовите метод executeBatch() для выполнения нескольких подготовленных операторов в пакетном режиме с целью повышения производительности.
Мирослав С.

Автор статей, ИБ-специалист