В этом руководстве вы узнаете, как выполнять пакетные операции в 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;
Выход:
Вывод показывает, что программа успешно вставила еще 30 строк в таблицу Authors.
Загрузите исходный код проекта
Загрузите исходный код проекта
Краткое содержание
- Используйте метод addBatch() для добавления подготовленного оператора в пакет.
- Вызовите метод executeBatch() для выполнения нескольких подготовленных операторов в пакетном режиме с целью повышения производительности.