CallableStatement

JDBC ma inny interfejs dla jeszcze bardziej złożonych scenariuszy. Dziedziczy on po PreparedStatement i nosi nazwę CallableStatement .

Służy do wywoływania (wywoływania) procedur składowanych w bazie danych. Osobliwością takiego wywołania jest to, że oprócz wyniku ResultSet do takiej procedury składowanej można również przekazać parametry.

Co nowego, pytasz? PreparedStatement ma również wynik ResultSet i można również przekazać do niego parametry. Tak, to prawda, ale osobliwością procedur przechowywanych jest to, że poprzez parametry mogą nie tylko odbierać, ale także zwracać dane.

Procedura składowana jest wywoływana z parametrami IN , OUT i INOUT . Zwraca jeden lub więcej obiektów ResultSet . Metoda Connection.prepareCall() służy do tworzenia obiektu CallableStatement .

Tutaj wyobraź sobie, że masz procedurę składowaną ADD, która akceptuje parametry a, b i c. Ta procedura dodaje aib i umieszcza wynik dodawania w zmiennej c.

Napiszmy kod, w którym spróbujemy go wywołać:

// Connect to the server
Connection connection = DriverManager.getConnection("jdbc:as400://mySystem");

// Create a CallableStatement object. It does preprocessing
// calling a stored procedure. Question marks
// indicate where the input parameters should be substituted, and where the output ones
// The first two parameters are input,
// and the third one is a day off.
CallableStatement statement = connection.prepareCall("CALL MYLIBRARY.ADD (?, ?, ?)");

// Setting up input parameters. Passing 123 and 234 to the procedure
statement.setInt (1, 123);
statement.setInt (2, 234);

// Registering the output parameter type
statement.registerOutParameter (3, Types.INTEGER);

// Run stored procedure
statement.execute();

// Get the value of the output parameter
int sum = statement.getInt(3);

// Close CallableStatement and Connection
statement.close();
connection.close();

Praca jest prawie jak z PreparedStatement , tylko jest pewien niuans. Nasza funkcja ADD zwraca wynik dodania w trzecim parametrze. Tylko obiekt CallableStatement nic o tym nie wie. Dlatego mówimy mu to wprost, wywołując metodę registerOutParameter() :

registerOutParameter(parameter number, Parameter type)

Następnie możesz wywołać procedurę za pomocą metody execute() , a następnie odczytać dane z trzeciego parametru za pomocą metody getInt() .

Żądania wsadowe

W rzeczywistych projektach często dochodzi do sytuacji, kiedy trzeba wykonać wiele zapytań tego samego typu (najczęstsze w tym przypadku jest PreparedStatement ), np. trzeba wstawić kilkadziesiąt lub kilkaset rekordów.

Jeśli wykonasz każde żądanie osobno, zajmie to dużo czasu i zmniejszy wydajność aplikacji. Aby temu zapobiec, możesz użyć trybu wstawiania wsadowego. Polega to na tym, że gromadzisz pewien bufor ze swoimi żądaniami, a następnie natychmiast je wykonujesz.

Oto fragment kodu jako przykład:

PreparedStatement stmt = con.prepareStatement(
        	"INSERT INTO jc_contact (first_name, last_name, phone, email) VALUES (?, ?, ?, ?)");

for (int i = 0; i < 10; i++) {
	// Fill in the request parameters
	stmt.setString(1, "FirstName_" + i);
    stmt.setString(2, "LastNAme_" + i);
    stmt.setString(3, "phone_" + i);
    stmt.setString(4, "email_" + i);
	// The request is not executed, but fits into the buffer,
	// which is then executed immediately for all commands
	stmt.addBatch();
}
// Execute all requests at once
int[] results = stmt.executeBatch();

Zamiast wykonywać zapytanie za pomocą metody execute() , wykonujemy je wsadowo za pomocą metody addBatch() .

A potem, gdy jest kilkaset żądań, możesz wysłać je wszystkie na raz do serwera, wywołując polecenie executeBatch() .

Zdrowy. Metoda executeBatch() zwraca tablicę liczb całkowitych — int[]. Każda komórka w tej tablicy zawiera liczbę wskazującą liczbę wierszy zmodyfikowanych przez odpowiednie zapytanie. Jeśli żądanie numer 3 w partii zmieniło 5 wierszy, to trzecia komórka tablicy będzie zawierała liczbę 5.