PreparedStatement

Последнее обновление: 08.08.2018

Кроме класса 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 < ?");
preparedStatement.setInt(1, maxPrice);
ResultSet resultSet = preparedStatement.executeQuery();
while(resultSet.next()){
									
	int id = resultSet.getInt("Id");
	String name = resultSet.getString("ProductName");
	int price = resultSet.getInt("Price");
					
	System.out.printf("%d. %s - %d \n", id, name, price);
}
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850