CallableStatement

JDBC har ett annat gränssnitt för ännu mer komplexa scenarier. Det ärver från PreparedStatement och kallas CallableStatement .

Den används för att anropa (Call) lagrade procedurer i databasen. Det speciella med ett sådant anrop är att, förutom ResultSet- resultatet , även parametrar kan skickas till en sådan lagrad procedur.

Vad är nytt, frågar du? PreparedStatement har också ett ResultSet- resultat och du kan även skicka parametrar till det. Ja, det är rätt, men det speciella med lagrade procedurer är att de genom parametrar inte bara kan ta emot, utan också returnera data.

Den lagrade proceduren anropas med IN , OUT och INOUT parametrar . Den returnerar ett eller flera ResultSet - objekt . Metoden Connection.prepareCall() används för att skapa ett CallableStatement- objekt .

Föreställ dig här att du har en lagrad procedur ADD som accepterar parametrarna a, b och c. Denna procedur lägger till a och b och placerar resultatet av additionen i variabeln c.

Låt oss skriva koden där vi ska försöka kalla den:

// 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();

Arbetet är nästan som med PreparedStatement , bara det finns en nyans. Vår ADD-funktion returnerar resultatet av tillägget i den tredje parametern. Endast CallableStatement- objektet vet ingenting om detta. Därför berättar vi detta explicit för honom genom att anropa metoden registerOutParameter() :

registerOutParameter(parameter number, Parameter type)

Efter det kan du anropa proceduren genom metoden execute() och sedan läsa data från den tredje parametern med metoden getInt() .

Batchningsförfrågningar

I riktiga projekt uppstår ofta en situation då man behöver göra mycket av samma typ av frågor (den vanligaste i det här fallet är PreparedStatement ), till exempel behöver man infoga flera tiotals eller hundratals poster.

Om du kör varje begäran separat kommer det att ta mycket tid och minska applikationens prestanda. För att förhindra detta kan du använda batchinsättningsläget. Det ligger i det faktum att du ackumulerar en viss buffert med dina förfrågningar och sedan exekverar dem omedelbart.

Här är en kodbit som exempel:

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();

Istället för att köra frågan med metoden execute() batchar vi den med addBatch()- metoden .

Och sedan, när det finns flera hundra förfrågningar, kan du skicka dem alla på en gång till servern genom att anropa kommandot executeBatch() .

Friska. Metoden executeBatch() returnerar en matris med heltal — int[]. Varje cell i denna array innehåller ett nummer som anger antalet rader som modifierats av motsvarande fråga. Om begäran nummer 3 i batch ändrade 5 rader, kommer den tredje cellen i arrayen att innehålla nummer 5.