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.
GO TO FULL VERSION