Что такое statement java
Перейти к содержимому

Что такое statement java

  • автор:

Как выбрать между Statement, PreparedStatement и CallableStatement?

Statement – SQL-выражение, подготовленное к выполнению в рамках определенной JDBC-сессии. Выполняется методом execute для обычного выражения, executeUpdate для модифицирующего, executeBatch для пакетного. Когда ожидаемый размер результата больше Integer.MAX_VALUE , используются версии методов executeLarge* .

После выполнения, экземпляр Statement владеет ResultSet-ом, и другими данными о результате выполнения, такими как количество обновленных записей и сгенерированные ключи.

PreparedStatement – предскомпилированная версия Statement , его наследник. Эффективнее выполняет одно и то же выражение множество раз. Входные параметры объявляются в SQL-выражении символом ? , следом сеттерами задаются их типы и значения. Делегирует обязанность экранировать введенные пользователем параметры базе данных.

CallableStatement – наследник PreparedStatement для вызова хранимых процедур. Кроме входных параметров, позволяет регистрировать выходные.

Экземпляры всех трех типов создаются методами интерфейса Connection .

Java JDBC Statement

Интерфейс Java JDBC, java.sql.Statement, используется для выполнения операторов SQL в реляционной базе данных. Вы получаете инструкцию JDBC из соединения JDBC. Если у вас есть экземпляр Java Statement, вы можете выполнить с ним запрос базы данных или обновление базы данных. В этом руководстве покажу как использовать Statement для выполнения запросов, обновлений и как правильно закрыть экземпляр Statement, когда вы закончите работу.

Создать заявление

Чтобы использовать Java JDBC Statement, сначала необходимо создать Statement.

Statement statement = connection.createStatement();

Экземпляр соединения является экземпляром Java JDBC Connection.

Выполнение запроса через оператор

Как только вы создали объект Java Statement, вы можете выполнить запрос к базе данных. Вы делаете это, вызывая его метод executeQuery(), передавая оператор SQL в качестве параметра. Метод Statement executeQuery() возвращает Java JDBC ResultSet, который можно использовать для навигации по ответу на запрос. Вот пример вызова Java JDBC Statement executeQuery() и навигации по возвращенному ResultSet:

String sql = «select * from people»; ResultSet result = statement.executeQuery(sql); while(result.next())

Помните, что ResultSet должен быть закрыт, когда вы закончите с ним.

Выполнить обновление через оператор

Вы также можете выполнить обновление базы данных с помощью экземпляра Java JDBC Statement. Например, вы можете выполнить вставку, обновление или удаление SQL через экземпляр Statement. Вот пример выполнения обновления базы данных с помощью экземпляра Java JDBC Statement:

Statement statement = connection.createStatement(); String sql = "update people set name='John' where rowsAffected = statement.executeUpdate(sql);

RowActed, возвращаемый вызовом Statement.executeUpdate(sql), сообщает, сколько записей в базе данных было затронуто оператором SQL.

Закрытие заявления

Как только вы закончили с экземпляром Statement, вам нужно закрыть его. Вы закрываете экземпляр Statement, вызывая его метод close(). Вот пример закрытия экземпляра Java JDBC Statement:

statement.close();

Закрытие оператора с помощью Java Try

Чтобы правильно закрыть оператор после использования, вы можете открыть его внутри блока Java Try With Resources. Вот пример закрытия экземпляра Java JDBC Statement с использованием конструкции try-with-resources:

try(Statement statement = connection.createStatement()) < //use the statement in here. >catch(SQLException e)

После выхода из блока try оператор Statement будет закрыт автоматически.

Заявление против PreparedStatement

Java JDBC API имеет интерфейс, похожий на оператор под названием PreparedStatement. PreparedStatement может иметь параметры, вставленные в оператор SQL, поэтому PreparedStatement можно использовать снова и снова с другими значениями параметров. Вы не можете сделать это с Заявлением. Оператор требует законченного оператора SQL в качестве параметра.

Руководство по JDBC. Утверждения (Statements).

В прошлом уроке мы изучили что такое соединение и способы его создания.
После того как соединение было установленно, мы можем начинать взаимодействие с базой данных (далее – БД).
Взаимодействовать с БД мы можем с помощью трёх интерфейсов, которые имплементируются каждым драйвером:

  • Statement
    Этот интерфейс используется для доступа к БД для общих целей. Он крайне полезен, когда мы используем статические SQL – выражения во время работы программы. Этот интерфейс не принимает никаких параметров.
  • PreparedStatement
    Этот интерфейс используется в случае, когда мы планируем использовать SQL – выражения множество раз. Он принимает параметры во время работы программы.
  • CallableStatement
    Этот интерфейс становится полезным в случае, когда мы хотим получить доступ к различным процедурам БД. Он также может принимать параметры во время работы программы.

Создание экземпляра Statement

Прежде, чем мы сможем использовать экземпляр Statement для выполнения SQL – запросов, нам необходимо создать такой экземпляр. Для этого используется метод Connection.createStatement(). В коде это выглядит таким образом:

 try < statement =connection.createStatement(); >catch (SQLException e) < e.printStackTrace(); >finally < /*Do some job. */ >

После этого мы можем использовать наш экземпляр statement для выполнения SQL – запросов.

Для этой цели интерфейс Statement имеет три метода, которые реализуются каждой конкретной реализацией JDBC драйвера:

  • boolean execute (String SQL)
    Этот метод возвращает логическое значение true, если объект ResultSet может быть получен. В противном случае он возвращает false. Он используется для выполнения DDL SQL – запросов ил в случаях, когда мы используем динамический SQL.
  • int executeUpdate (String SQL)
    Этот метода возвращает количество столбцов в таблице, на которое повлиял наш SQL – запрос. Мы используем этот метод для выполнения SQL – запросов, когда хотим получить количество задействованных столбцов, например количество данных по определённому запросу.
  • ResultSet executeQuery (String SQL)
    Этот метод возвращает нам экземпляр ResultSet. Мы используем этот метод в случаях, когда мы рассчитываем получить множество объектов в результате выполнения нашего SQL – запроса. Например, при получении списка элементов, которые удовлетворяют определённым условиям.

Закрытие экземпляра Statement

Когда мы закрываем наше соединение (Connection) для сохранения результатов в БД мы таким же образом закрываем и экземпляр Statement.

Для этого мы используем метод close().

Рассмотрим, как это выглядит в нашем коде:

 Connection connection = null; Statement statement = null; Class.forName(JDBC_DRIVER); connection = DriverManager.getConnection(DATABASE_URL, USER, PASSWORD); try < statement = connection.createStatement(); >catch (SQLException e) < e.printStackTrace(); >finally < if (statement != null) < statement.close(); >> 

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

 import java.sql.*; public class StatementDemo < static final String JDBC_DRIVER = "com.mysql.jdbc.Driver"; static final String DATABASE_URL = "jdbc:mysql://localhost/PROSELYTE_TUTORIALS"; static final String USER = "ИМЯ_ПОЛЬЗОВАТЕЛЯ"; static final String PASSWORD = "ВАШ_ПАРОЛЬ"; public static void main(String[] args) throws ClassNotFoundException, SQLException < Connection connection = null; Statement statement = null; System.out.println("Registering JDBC driver. "); Class.forName(JDBC_DRIVER); System.out.println("Connecting to database. "); connection = DriverManager.getConnection(DATABASE_URL, USER, PASSWORD); System.out.println("Creating statement. "); statement = connection.createStatement(); String sql = "SELECT * FROM developers"; Boolean isRetrieved = statement.execute(sql); System.out.println("Is data retrieved: " + isRetrieved); System.out.println("Displaying retrieved data:"); ResultSet resultSet = statement.executeQuery(sql); while (resultSet.next()) < int String name = resultSet.getString("name"); String specialty = resultSet.getString("specialty"); int salary = resultSet.getInt("salary"); System.out.println("id: " + id); System.out.println("Name: " + name); System.out.println("Specialty: " + specialty); System.out.println("Salary: " + salary); System.out.println("\n===================\n"); >System.out.println("Closing connection and releasing resources. "); try < resultSet.close(); statement.close(); connection.close(); >finally < if(statement !=null)< statement.close(); >if(connection!=null) < connection.close(); >> System.out.println("Thank You."); > > 

В результате работы программы мы получим следующий результат:

 /*Some System Messages*/ Registering JDBC driver. Connecting to database. Creating statement. Is data retrieved: true Displaying retrieved data: id: 1 Name: Proselyte Specialty: Java Salary: 2000 =================== id: 2 Name: Peter Specialty: C++ Salary: 3000 =================== id: 3 Name: AsyaSmile Specialty: UI/UX Salary: 2000 =================== Closing connection and releasing resources. Thank You. 

Создание экземпляра PreparedStatement

PreparedStatement наследует интерфейс Statement, что даёт нам определённые преимущества перед обычным Statement. В частности, мы получаем большую гибкость при динамической поддержке аргументов.

Вот как выглядит создание экземпляра PreparedStatement на практике:

 try < String SQL = "Update developers SET salary WHERE specialty = ?"; preparedStatement = connection.prepareStatement(SQL); >catch (SQLException e)< e.printStackTrace(); >finally < /*do some job. */ >

Все параметры, которые отмечены символом ? называются маркерами параметра. Это означает, что они должны быть переданы через параметры метода.

Каждый параметр ссылается на свой порядковый номер в сигнатуре метода. Т.е. первый маркер находится на первом месте, второй – на втором и т.д. В отличие от массивов, здесь отсчёт идёт с 1. Это связано с особенностями реляционной модели, на которой и основана работа реляционных БД.

Для выполнения SQL – запросов используются методы с такими же названиями (execute(), executeQuery, executeUpdate), которые несколько модифицированы.

Закрытие экземпляра PreparedStatement

Когда мы закрываем наше соединение (Connection) для сохранения результатов в БД мы таким же образом закрываем и экземпляр PreparedStatement.

Для этого мы используем метод close().

Рассмотрим, как это выглядит в нашем коде:

 try < String SQL = "Update developers SET salary WHERE specialty = ?"; preparedStatement = connection.prepareStatement(SQL); >catch (SQLException e) < e.printStackTrace(); >finally < if (preparedStatement != null) < preparedStatement.close(); >> 

Для понимания того, как это работает на практике, рассмотрим пример простого приложения с использованием PreparedStatement.
Пример:

 import java.sql.*; public class PreparedStatementDemo < static final String JDBC_DRIVER = "com.mysql.jdbc.Driver"; static final String DATABASE_URL = "jdbc:mysql://localhost/PROSELYTE_TUTORIALS"; static final String USER = "ИМЯ_ПОЛЬЗОВАТЕЛЯ"; static final String PASSWORD = "ВАШ_ПАРОЛЬ"; public static void main(String[] args) throws ClassNotFoundException, SQLException < Connection connection = null; PreparedStatement preparedStatement = null; System.out.println("Registering JDBC driver. "); Class.forName(JDBC_DRIVER); System.out.println("Creating connection. "); connection = DriverManager.getConnection(DATABASE_URL, USER, PASSWORD); try < String SQL = "SELECT * FROM developers"; preparedStatement = connection.prepareStatement(SQL); System.out.println("Initial developers table content:"); ResultSet resultSet = preparedStatement.executeQuery(SQL); while (resultSet.next()) < int String name = resultSet.getString("name"); String specialty = resultSet.getString("specialty"); int salary = resultSet.getInt("salary"); System.out.println("id: " + id); System.out.println("Name: " + name); System.out.println("Specialty: " + specialty); System.out.println("Salary: " + salary); System.out.println("\n============================\n"); >SQL = "Update developers SET salary=? WHERE specialty=?"; System.out.println("Creating statement. "); System.out.println("Executing SQL query. "); preparedStatement = connection.prepareStatement(SQL); preparedStatement.setInt(1, 3000); preparedStatement.setString(2, "java"); System.out.println("Rows impacted: " + preparedStatement.executeUpdate()); System.out.println("Final developers table content:"); SQL = "SELECT * FROM developers"; resultSet = preparedStatement.executeQuery(SQL); while (resultSet.next()) < int String name = resultSet.getString("name"); String specialty = resultSet.getString("specialty"); int salary = resultSet.getInt("salary"); System.out.println("id: " + id); System.out.println("Name: " + name); System.out.println("Specialty: " + specialty); System.out.println("Salary: " + salary); System.out.println("\n============================\n"); >> catch (SQLException e) < e.printStackTrace(); >finally < if (preparedStatement != null) < preparedStatement.close(); >if(connection!=null) < connection.close(); >> System.out.println("Thank You."); > > 

В результате работы программы мы получим, примерно, следующий результат:

 /*Some System Messages*/ Registering JDBC driver. Creating connection. Initial developers table content: id: 1 Name: Proselyte Specialty: Java Salary: 2000 ============================ id: 2 Name: Peter Specialty: C++ Salary: 3000 ============================ id: 3 Name: AsyaSmile Specialty: UI/UX Salary: 2000 ============================ id: 4 Name: Eugene Specialty: Java Salary: 2200 ============================ Creating statement. Executing SQL query. Rows impacted: 2 Final developers table content: id: 1 Name: Proselyte Specialty: Java Salary: 3000 ============================ id: 2 Name: Peter Specialty: C++ Salary: 3000 ============================ id: 3 Name: AsyaSmile Specialty: UI/UX Salary: 2000 ============================ id: 4 Name: Eugene Specialty: Java Salary: 3000 ============================ Thank You. 

В этом приложении мы сначала получаем и выводим в консоль список всех записей из таблицы developer, после чего устанавливаем salary = 3000 для всех разработчиков, у которых specialty = “Java”.

Создание экземпляра CallableStatement

Экземпляр CallableStatement используется для выполнения процедур, непосредственно в самой БД.

Рассмотрим пример, в котором нам необходимо выполнить такую процедуру в MySQL:

 DELIMITER $ DROP PROCEDURE IF EXISTS `developers`.`getDeveloperName` $ CREATE PROCEDURE PROSELYTE_TUTORIALS.`getDeveloperName` (IN DEVELOPER_ID INT, OUT DEVELOPER_NAME VARCHAR(50)) BEGIN SELECT first INTO DEVELOPER_NAME FROM developers WHERE $ DELIMITER ; 

Существует три типа параметров: IN, OUT, INOUT. PreparedStatement использует только IN, а CallableStatement, в свою очередь, использует все три.

Рассмотрим, что же это за параметры:

  • IN
    Параметр, значение которого известно в момент, когда создаётся запрос. Мы назначаем параметр IN с помощью метода типа setXXX().
  • OUT
    Параметр, значение которого возвращается SQL – запросом. Мы получаем значения из OUT с помощью методов типа getXXX().
  • INOUT
    Параметр, который использует входные и выходные значения. Мы назначаем параметр с помощью метода типа setXXX(), а получаем значения, с помощью метода типа getXXX().

В коде, создание экземпляра CallableStatement выглядит следующим образом:

 try < String SQL = ""; callableStatement = connection.prepareCall(SQL); >finally < /* do some job */ >

Строка SQL представляет собой процедуру, с параметрами.

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

Когда мы используем параметры типа OUT и INOUT, нам необходимо задействовать дополнительный метод registerOutParameter(). Этот метод устанавливает тип данных JDBC в тип данных процедуры.

После того как мы вызвали процедуру, мы получаем значение из параметра OUT с помощью соответствующего метода getXXX(). Этот метод преобразует полученное значение из типа данных SQL в тип данных Java.

Закрытие экземпляра CallableStatement

Когда мы закрываем наше соединение (Connection) для сохранения результатов в БД мы таким же образом закрываем и экземпляр Statement.

Для этого мы используем метод close().

Рассмотрим, как это выглядит в нашем коде:

 try < String SQL = ""; callableStatement = connection.prepareCall(SQL); >finally < if(callableStatement!=null)< callableStatement.close(); >> 

Для понимания того, как это работает на практике, рассмотрим пример простого приложения
Пример:

Создаём процедуру в нашей БД:

 DELIMITER $ DROP PROCEDURE IF EXISTS PROSELYTE_TUTORIALS.`getDeveloperName` $ CREATE PROCEDURE PROSELYTE_TUTORIALS.`getDeveloperName` (IN DEVELOPER_ID INT, OUT DEVELOPER_NAME VARCHAR(50)) BEGIN SELECT name INTO DEVELOPER_NAME FROM developers WHERE $ DELIMITER ; 
 import java.sql.*; public class CallableStatementDemo < static final String JDBC_DRIVER = "com.mysql.jdbc.Driver"; static final String DATABASE_URL = "jdbc:mysql://localhost/PROSELYTE_TUTORIALS"; static final String USER = "ВАШЕ_ИМЯ_ПОЛЬЗОВАТЕЛЯ"; static final String PASSWORD = "ВАШ_ПАРОЛЬ"; public static void main(String[] args) throws ClassNotFoundException, SQLException < Connection connection = null; CallableStatement callableStatement = null; System.out.println("Registering JDBC driver. "); Class.forName(JDBC_DRIVER); System.out.println("Creating connection. "); connection = DriverManager.getConnection(DATABASE_URL, USER, PASSWORD); System.out.println("Creating callable statement. "); try < String SQL = ""; callableStatement = connection.prepareCall(SQL); int developerID = 1; callableStatement.setInt(1, developerID); callableStatement.registerOutParameter(2, Types.VARCHAR); System.out.println("Executing procedure. "); callableStatement.execute(); String developerName = callableStatement.getString(2); System.out.println("Developer INFO"); System.out.println("id: " + developerID); System.out.println("Name: " + developerName); > finally < if (callableStatement != null) < callableStatement.close(); >if (connection != null) < connection.close(); >> System.out.println("Thank You."); > > 

В результате работы программы мы получим следующий результат:

 /*Some System Messages*/ Registering JDBC driver. Creating connection. Creating callable statement. Executing procedure. Developer INFO id: 1 Name: Proselyte Thank You. 

В этом уроке мы изучили утверждения (statements) их виды и рассмотрели примеры приложений с их использованием.

В следующем уроке мы изучим такой элемент, как Result Set.

Что такое statement java

Кроме класса Statement в java.sql мы можем использовать для выполнения запросов еще один класс — PreparedStatement . Кроме собственно выполнения запроса этот класс позволяет подготовить запрос, отформатировать его должным образом.

Например, в прошлых темах была создана таблица, которая имеет три столбца:

CREATE TABLE products ( Id INT PRIMARY KEY AUTO_INCREMENT, ProductName VARCHAR(20), Price INT )

С помощью PreparedStatement добавим в нее один объект:

import java.sql.*; import java.util.Scanner; public class Program < public static void main(String[] args) < try< String url = "jdbc:mysql://localhost/store?serverTimezone=Europe/Moscow&useSSL=false"; String username = "root"; String password = "password"; Scanner scanner = new Scanner(System.in); Class.forName("com.mysql.cj.jdbc.Driver").getDeclaredConstructor().newInstance(); System.out.print("Input product name: "); String name = scanner.nextLine(); System.out.print("Input product price: "); int price = scanner.nextInt(); try (Connection conn = DriverManager.getConnection(url, username, password))< String sql = "INSERT INTO Products (ProductName, Price) Values (?, ?)"; PreparedStatement preparedStatement = conn.prepareStatement(sql); preparedStatement.setString(1, name); preparedStatement.setInt(2, price); int rows = preparedStatement.executeUpdate(); System.out.printf("%d rows added", rows); >> catch(Exception ex) < System.out.println("Connection failed. "); System.out.println(ex); >> >

В данном случае данные вводятся с консоли и затем добавляются в базу данных. Для создания объекта PreparedStatement применяется метод prepareStatement() класса Connection. В этот метод передается выражение sql INSERT INTO Products (ProductName, Price) Values (?, ?) . Это выражение может содержать знаки вопроса ? — знаки подстановки, вместо которых будут вставляться реальные значения.

Чтобы связать отдельные знаки подстановки с конкретными значениями у класса PreparedStatement определен ряд методов для различных типов данных. Все методы, которые поставляют значения вместо знаков подстановки, в качестве первого параметра принимают порядковый номер знака подстановки (нумерация начинается с 1), а в качестве второго параметра — собственно значение, которое вставляется вместо знака подстановки.

Например, первый знак подстановки ? в выражении sql представляет значение для столбца ProductName, который хранит строку. Поэтому для связи значения с первым знаком подстановки применяется метод preparedStatement.setString(1, name) .

Второй знак подстановки должен передавать значение для столбца Price, который хранит целые числа. Поэтому для вставик значения используется метод preparedStatement.setInt(2, price)

Кроме setString и setInt PreparedStatement имеет еще ряд подобных методов, которые работают подобным образом. Некоторые из них:

  • setBigDecimal
  • setBoolean
  • setDate
  • setDouble
  • setFloat
  • setLong
  • setNull
  • setTime

Для выполнения запроса PreparedStatement имеет три метода:

  • boolean execute() : выполняет любую SQL-команду
  • ResultSet executeQuery() : выполняет команду SELECT, которая возвращает данные в виде ResultSet
  • int executeUpdate() : выполняет такие SQL-команды, как INSERT, UPDATE, DELETE, CREATE и возвращает количество измененных строк

При этом в отличие от методов Statement эти методы не принимают SQL-выражение.

Пример выполнения программы:

C:\Java>javac Program.java C:\Java>java -classpath c:\Java\mysql-connector-java-8.0.11.jar;c:\Java Program Inpit product name: Xiaomi Mi 8 Input product price: 35000 1 rows added C:\Java>

Подобным образом мы можем выполнять и другие выражения. Например, получим товары, у которых цена меньше 50000:

int maxPrice = 50000; PreparedStatement preparedStatement = conn.prepareStatement(«SELECT * FROM Products WHERE Price

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *