Автор оригинала: Pankaj Kumar.
- Java PreparedStatement-это просто утверждение, и оно является частью платформы Java JDBC.
- Он используется для выполнения операций crud с базой данных.
- PreparedStatement расширяет интерфейс оператора.
- Подготовленный оператор считается более безопасным, поскольку он поддерживает параметризованные запросы. Подготовленный оператор также предотвращает атаки с использованием SQL – инъекций.
- Мы можем получить экземпляр PreparedStatement , вызвав prepareStatement(строковый запрос) метод Подключения , как показано ниже.
// Method : public PreparedStatement prepareStatement(String query)throws SQLException{} // Usage : Connection con = DriverManager.getConnection ("jdbc:mysql://localhost:3306/customerdb", "root", "root"); PreparedStatement ps = con.prepareStatement("select id, firstname, lastname, email, birthdate from tblcustomer");
Преимущества подготовленного заявления
- Подготовленный оператор может использоваться как для параметризованного запроса, так и для обычного запроса.
- Производительность запроса PreparedStatement лучше, чем у оператора.
- Экземпляр PreparedStatement может быть повторно использован для выполнения одного и того же запроса с различными параметрами.
- Подготовленное заявление сохраняет приложение от атак с использованием SQL-инъекций.
Подготовленные методы оценки
Мы можем разделить методы на разные категории.
1. Выполнение запроса
- ResultSet ExecuteQuery() : Этот метод используется для выполнения операции чтения с использованием объекта PreparedStatement. Он возвращает экземпляр набора результатов, используемого для получения данных.
- int executeUpdate() : Этот метод используется для выполнения запросов на вставку, удаление и обновление. Он вернет целое значение, указывающее номер строки базы данных, на которую повлиял запрос.
2. Передача значений параметров в запрос
Все приведенные ниже методы имеют 2 аргумента. 1-й аргумент-это индекс параметра, а 2-й аргумент-значение параметра.
- void SetInt(int parameterIndex, значение int) : Этот метод устанавливает целочисленное значение в указанный индекс параметра.
- void setShort(int parameterIndex, короткое значение) : Этот метод устанавливает короткое значение в указанный индекс параметра.
- void setLong(int parameterIndex, длинное значение) : Этот метод устанавливает длинное значение в указанный индекс параметра.
- void SetFloat(int parameterIndex, значение с плавающей точкой) : Этот метод устанавливает значение с плавающей точкой в указанный индекс параметра.
- void setDouble(int parameterIndex, двойное значение) : Этот метод устанавливает двойное значение в указанный индекс параметра.
- void setBigDecimal(int parameterIndex, значение BigDecimal) : Этот метод устанавливает значение BigDecimal в указанный индекс параметра.
- void setString(int parameterIndex, строковое значение) : Этот метод устанавливает строковое значение в указанный индекс параметра.
- void setDate(int parameterIndex, значение даты) : Этот метод устанавливает значение даты в указанный индекс параметра.
Примечание : Значение parameterIndex начинается с 1, и все эти методы вызывают Исключение SQLException .
Пример подготовленного утверждения Java
Мы будем использовать базу данных MySQL, чтобы продемонстрировать использование Preparedstatement. Используйте приведенные ниже сценарии БД для создания базы данных, таблиц и примеров данных.
create database customerdb; use customerdb; create table tblcustomer( id integer AUTO_INCREMENT primary key, firstname varchar(32), lastname varchar(32), email varchar(32), birthdate datetime ); insert into tblcustomer (id,firstname,lastname,email,birthdate) values(1,'Ricky','Smith','ricky@google.com','2001-12-10');
Информация о подключении к базе данных:
Имя базы данных MySQL: customerdb IP: локальный хост Порт: 3306 имя пользователя: root пароль: root
Зависимость от Maven :
mysql mysql-connector-java 5.1.48
1. Получите данные с помощью PreparedStatement
В этом случае мы получим строку с указанным идентификатором из tblcustomer . Запрос вернет одну строку.
package com.journaldev.examples; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; public class PreparedStatementDemo { public static void main(String[] args) throws Exception { Connection con = null; PreparedStatement ps = null; ResultSet rs = null; int customerId = 1; String query = "select id, firstname, lastname, email, birthdate from tblcustomer where id = ?"; try { Class.forName("com.mysql.jdbc.Driver"); con = DriverManager.getConnection("jdbc:mysql://localhost:3306/customerdb", "root", "root"); ps = con.prepareStatement(query); ps.setInt(1, customerId); rs = ps.executeQuery(); while (rs.next()) { System.out.println("Id:" + rs.getInt(1)); System.out.println("First Name:" + rs.getString(2)); System.out.println("Last Name:" + rs.getString("lastname")); System.out.println("Email:" + rs.getString("email")); System.out.println("BirthDate:" + rs.getDate("birthdate")); } } catch (Exception e) { e.printStackTrace(); } finally { rs.close(); ps.close(); con.close(); } } }
Понимание этапов выполнения:
Шаг 1: Загрузка драйвера JDBC.
Класс. forName ( “com.mysql.jdbc.Драйвер” ) загружает драйвер jdbc в память.
Шаг 2 : Теперь нам нужно получить объект подключения. Это сделает следующая строка.
Шаг 2 : Теперь нам нужно получить объект подключения. Это сделает следующая строка.
Шаг 3: Мы можем получить экземпляр PreparedStatement из объекта подключения. Нам также нужно указать запрос, который мы хотим выполнить. например
Подготовленное заявление.Подготовленное заявление( <<Запрос>> );
Подготовленный оператор также поддерживает параметризованный запрос.
‘?’ является параметром в запросе. Значение этого параметра необходимо указать перед выполнением запроса.
Шаг 4: Предоставление значений параметров запроса. В приведенном выше примере есть только один параметр, т. е. идентификатор типа integer.
int; ps.SetInt(1, Идентификатор пользователя); метод set Int(<<Номер параметра>>,<<Значение параметра>) имеет 2 аргумента. В приведенном выше примере ” 1 ” – это номер параметра, а переменная CustomerID-значение параметра.
Шаг 5: Выполнение запроса.
Метод ExecuteQuery() PreparedStatement используется для выполнения запроса select. Он вернет экземпляр набора результатов. Если ваш запрос предназначен для вставки, обновления или удаления, вы можете использовать executeUpdate() .
Шаг 6: Итерационный набор результатов. метод набора результатов next() используется для получения выходных данных запроса.
Шаг 7: Закрытие ресурсов: Это один из важных шагов. Многие разработчики забывают закрыть такие ресурсы, как ResultSet, PreparedStatement и Подключение. Это приведет к утечке ресурсов, которая может привести к сбою в работе вашего приложения.
Вывод программы:
Id:1 First Name:Ricky Last Name:Smith Email:ricky@google.com BirthDate:2001-12-1
2. Операция вставки с использованием PreparedStatement
В этом примере мы будем использовать PreparedStatement для выполнения операции вставки в таблицу tblcustomer.
package com.journaldev.examples; import java.sql.*; import java.text.SimpleDateFormat; public class PrepareStatementInsertDemo { public static void main(String[] args) throws Exception { { Connection con = null; PreparedStatement ps = null; ResultSet rs = null; String firstname = "matthew"; String lastname = "wade"; String email = "matthew@java.com"; Date birthdate = new Date(new SimpleDateFormat("YYYY-MM-DD").parse("2000-12-12").getTime()); String query = "insert into tblcustomer (id,firstname,lastname,email,birthdate) values(default,?,?,?,?)"; try { Class.forName("com.mysql.jdbc.Driver"); con = DriverManager.getConnection("jdbc:mysql://localhost:3306/customerdb", "root", "root"); ps = con.prepareStatement(query, Statement.RETURN_GENERATED_KEYS); ps.setString(1, firstname); ps.setString(2, lastname); ps.setString(3, email); ps.setDate(4, birthdate); int row = ps.executeUpdate(); System.out.println("No. of Rows inserted:" + row); rs = ps.getGeneratedKeys(); if (rs.next()) { System.out.println("Id of new Customer:" + rs.getInt(1)); } } catch (Exception e) { e.printStackTrace(); } finally { rs.close(); ps.close(); con.close(); } } } }
В этом примере при создании экземпляра PreparedStatement мы передали 2 аргумента. 1-й-это сам запрос, а 2 nd – это “Оператор. RETURN_GENERATED_KEYS “, что поможет нам получить значение первичного ключа новой строки.
Приведенный ниже код используется для предоставления параметров для запроса вставки.
ps.setString(1, firstname); ps.setString(2, lastname); ps.setString(3, email); ps.setDate(4, birthdate);
Как указано в предыдущей программе, для выполнения операции вставки используется метод executeUpdate (). Он вернет количество строк, на которые повлиял наш запрос.
Вывод программы:
No. of Rows inserted:1 Id of new Customer:2
Если вы зайдете в базу данных и выполните запрос select, то увидите результат ниже.
mysql> use customerdb; Database changed mysql> select * from tblcustomer; +----+-----------+----------+------------------+---------------------+ | id | firstname | lastname | email | birthdate | +----+-----------+----------+------------------+---------------------+ | 1 | Ricky | Smith | ricky@google.com | 2001-12-10 00:00:00 | | 2 | matthew | wade | matthew@java.com | 1999-12-26 00:00:00 | +----+-----------+----------+------------------+---------------------+ 2 rows in set (0.00 sec)
3. Операция обновления с использованием PreparedStatement
Теперь мы выполним операцию обновления. Мы обновим имя и фамилию клиента, имеющего электронную почту “matthew@java.com”. Эта строка была вставлена в предыдущем примере.
package com.journaldev.examples; import java.sql.*; public class PrepareStatementUpdateDemo { public static void main(String[] args) throws Exception { { Connection con = null; PreparedStatement ps = null; String email = "matthew@java.com"; String newFirstname = "john"; String newLastname = "smith"; String query = "update tblcustomer set firstname = ?,lastname =? where email = ?"; try { Class.forName("com.mysql.jdbc.Driver"); con = DriverManager.getConnection("jdbc:mysql://localhost:3306/customerdb", "root", "root"); ps = con.prepareStatement(query); ps.setString(1, newFirstname); ps.setString(2, newLastname); ps.setString(3, email); int row = ps.executeUpdate(); System.out.println("No. of Rows Updated:" + row); if (row == 1) { String selectQuery = "select id,firstname,lastname,email,birthdate from tblcustomer where email=?"; try (PreparedStatement selStatement = con.prepareStatement(selectQuery); ) { selStatement.setString(1, email); ResultSet rs = selStatement.executeQuery(); if (rs.next()) { System.out.println("Id:" + rs.getInt(1)); System.out.println("First Name:" + rs.getString(2)); System.out.println("Last Name:" + rs.getString("lastname")); System.out.println("Email:" + rs.getString("email")); System.out.println("BirthDate:" + rs.getDate("birthdate")); } rs.close(); } } } catch (Exception e) { e.printStackTrace(); } finally { ps.close(); con.close(); } } } }
Понимание программы:
В приведенном выше примере у нас есть 3 параметра в запросе. 1 st – новое имя, 2 nd – новая фамилия и 3 rd – адрес электронной почты клиента.
Приведенная ниже строка кода предоставляет значение этого параметра для Подготовленной инструкции.
ps.setString(1, newFirstname); ps.setString(2, newLastname); ps.setString(3, email);
Метод executeUpdate() используется для выполнения запроса на обновление. Он вернет количество строк, обновленных запросом.
Вывод программы:
No. of Rows Updated:1 Id:2 First Name:john Last Name:smith Email:matthew@java.com BirthDate:1999-12-26
Вы можете проверить обновление в базе данных с помощью SQL-запроса.
mysql> select * from tblcustomer; +----+-----------+----------+------------------+---------------------+ | id | firstname | lastname | email | birthdate | +----+-----------+----------+------------------+---------------------+ | 1 | Ricky | Smith | ricky@google.com | 2001-12-10 00:00:00 | | 2 | john | smith | matthew@java.com | 1999-12-26 00:00:00 | +----+-----------+----------+------------------+---------------------+ 2 rows in set (0.00 sec)
4. Удалите операцию с помощью PreparedStatement
Теперь мы удалим запись клиента, имеющую электронную почту “matthew@java.com”.
package com.journaldev.examples; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; public class PrepareStatementDeleteDemo { public static void main(String[] args) throws Exception { { Connection con = null; PreparedStatement ps = null; String email = "matthew@java.com"; String query = "delete from tblcustomer where email = ?"; try { Class.forName("com.mysql.jdbc.Driver"); con = DriverManager.getConnection("jdbc:mysql://localhost:3306/customerdb", "root", "root"); ps = con.prepareStatement(query); ps.setString(1, email); int row = ps.executeUpdate(); System.out.println("No. of Rows Deleted:" + row); } catch (Exception e) { e.printStackTrace(); } finally { ps.close(); con.close(); } } } }
Пакетные методы в подготовленном отчете
- void addBatch() : Этот метод используется для добавления наборов параметров в пакет этого объекта PreparedStatement для обновления нескольких строк.
- int[] executeBatch() : Этот метод выполняет все SQL-запросы из пакета объекта PreparedStatement и возвращает массив счетчиков обновлений. Этот метод вызывает исключение BatchUpdateException, если он не выполняется, и драйвер JDBC может продолжать или не продолжать обработку оставшегося пакета.
Пакетная/массовая операция с использованием PreparedStatement
package com.journaldev.examples; import java.sql.*; import java.text.SimpleDateFormat; public class PrepareStatementBatchDemo { public static void main(String[] args) throws Exception { { Connection con = null; PreparedStatement ps = null; ResultSet rs = null; SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-DD"); String query = "insert into tblcustomer (id,firstname,lastname,email,birthdate) values(default,?,?,?,?)"; try { Class.forName("com.mysql.jdbc.Driver"); con = DriverManager.getConnection("jdbc:mysql://localhost:3306/customerdb", "root", "root"); ps = con.prepareStatement(query, Statement.RETURN_GENERATED_KEYS); // 1st Insert ps.setString(1, "Ross"); ps.setString(2, "Southee"); ps.setString(3, "ross@java.com"); ps.setDate(4, new Date(sdf.parse("2000-12-12").getTime())); ps.addBatch(); // 2nd Insert ps.setString(1, "Mayank"); ps.setString(2, "Kohli"); ps.setString(3, "mayank@java.com"); ps.setDate(4, new Date(sdf.parse("2005-12-12").getTime())); ps.addBatch(); // 3rd Insert ps.setString(1, "Tom"); ps.setString(2, "Patel"); ps.setString(3, "tom@java.com"); ps.setDate(4, new Date(sdf.parse("1995-12-12").getTime())); ps.addBatch(); // Execution int[] rows = ps.executeBatch(); for (int row : rows) { System.out.println("No. of Rows inserted:" + row); } rs = ps.getGeneratedKeys(); while (rs.next()) { System.out.println("Id of new Customer:" + rs.getInt(1)); } } catch (Exception e) { e.printStackTrace(); } finally { rs.close(); ps.close(); con.close(); } } } }
В приведенном выше примере мы вставили 3 записи о клиентах в одну партию. Более эффективно вставлять несколько строк в пакет вместо одной строки. Метод addBatch() добавляет данные в пакет. Функция executeBatch() выполняет все запросы в пакете.
Выход:
No. of Rows inserted:1 No. of Rows inserted:1 No. of Rows inserted:1 Id of new Customer:10 Id of new Customer:11 Id of new Customer:12
Ссылка : Javadoc