JDBC - Instruções, PreparedStatement e CallableStatement
Assim que uma conexão for obtida, podemos interagir com o banco de dados. As interfaces JDBC Statement, CallableStatement e PreparedStatement definem os métodos e propriedades que permitem enviar comandos SQL ou PL / SQL e receber dados de seu banco de dados.
Eles também definem métodos que ajudam a fazer a ponte entre as diferenças de tipo de dados entre os tipos de dados Java e SQL usados em um banco de dados.
A tabela a seguir fornece um resumo da finalidade de cada interface para decidir sobre a interface a ser usada.
Interfaces | Uso recomendado |
---|---|
Declaração | Use isso para acesso de propósito geral ao seu banco de dados. Útil quando você está usando instruções SQL estáticas em tempo de execução. A interface de instrução não pode aceitar parâmetros. |
Declaração preparada | Use isso quando você planeja usar as instruções SQL muitas vezes. A interface PreparedStatement aceita parâmetros de entrada em tempo de execução. |
CallableStatement | Use-o quando quiser acessar os procedimentos armazenados do banco de dados. A interface CallableStatement também pode aceitar parâmetros de entrada de tempo de execução. |
Os objetos de declaração
Criando Objeto de Declaração
Antes de usar um objeto Statement para executar uma instrução SQL, você precisa criar um usando o método createStatement () do objeto Connection, como no exemplo a seguir -
Statement stmt = null;
try {
stmt = conn.createStatement( );
. . .
}
catch (SQLException e) {
. . .
}
finally {
. . .
}
Depois de criar um objeto Statement, você pode usá-lo para executar uma instrução SQL com um de seus três métodos de execução.
boolean execute (String SQL): Retorna um valor booleano verdadeiro se um objeto ResultSet puder ser recuperado; caso contrário, retorna falso. Use este método para executar instruções SQL DDL ou quando precisar usar SQL verdadeiramente dinâmico.
int executeUpdate (String SQL): Retorna o número de linhas afetadas pela execução da instrução SQL. Use este método para executar instruções SQL para as quais espera obter um número de linhas afetadas - por exemplo, uma instrução INSERT, UPDATE ou DELETE.
ResultSet executeQuery (String SQL): Retorna um objeto ResultSet. Use este método quando você espera obter um conjunto de resultados, como faria com uma instrução SELECT.
Objeto de declaração de fechamento
Assim como você fecha um objeto Connection para economizar recursos do banco de dados, pelo mesmo motivo você também deve fechar o objeto Statement.
Uma chamada simples para o método close () fará o trabalho. Se você fechar o objeto Connection primeiro, ele fechará também o objeto Statement. No entanto, você deve sempre fechar explicitamente o objeto Statement para garantir uma limpeza adequada.
Statement stmt = null;
try {
stmt = conn.createStatement( );
. . .
}
catch (SQLException e) {
. . .
}
finally {
stmt.close();
}
Para um melhor entendimento, sugerimos que você estude o tutorial Declaração - Exemplo .
Os objetos PreparedStatement
A interface PreparedStatement estende a interface Statement, que oferece funcionalidade adicional com algumas vantagens sobre um objeto Statement genérico.
Esta instrução oferece a flexibilidade de fornecer argumentos dinamicamente.
Criação do objeto PreparedStatement
PreparedStatement pstmt = null;
try {
String SQL = "Update Employees SET age = ? WHERE id = ?";
pstmt = conn.prepareStatement(SQL);
. . .
}
catch (SQLException e) {
. . .
}
finally {
. . .
}
Todos os parâmetros em JDBC são representados pelo ?símbolo, que é conhecido como marcador de parâmetro. Você deve fornecer valores para cada parâmetro antes de executar a instrução SQL.
o setXXX() métodos vinculam valores aos parâmetros, onde XXXrepresenta o tipo de dados Java do valor que você deseja vincular ao parâmetro de entrada. Se você esquecer de fornecer os valores, receberá uma SQLException.
Cada marcador de parâmetro é referido por sua posição ordinal. O primeiro marcador representa a posição 1, a próxima posição 2 e assim por diante. Este método difere dos índices de array Java, que começa em 0.
Todos os Statement object'sos métodos de interação com o banco de dados (a) execute (), (b) executeQuery () e (c) executeUpdate () também funcionam com o objeto PreparedStatement. No entanto, os métodos são modificados para usar instruções SQL que podem inserir os parâmetros.
Fechando o objeto PreparedStatement
Assim como você fecha um objeto Statement, pelo mesmo motivo você também deve fechar o objeto PreparedStatement.
Uma chamada simples para o método close () fará o trabalho. Se você fechar o objeto Connection primeiro, ele também fechará o objeto PreparedStatement. No entanto, você deve sempre fechar explicitamente o objeto PreparedStatement para garantir a limpeza adequada.
PreparedStatement pstmt = null;
try {
String SQL = "Update Employees SET age = ? WHERE id = ?";
pstmt = conn.prepareStatement(SQL);
. . .
}
catch (SQLException e) {
. . .
}
finally {
pstmt.close();
}
Para um melhor entendimento, vamos estudar Prepare - Exemplo de Código .
Os objetos CallableStatement
Assim como um objeto Connection cria os objetos Statement e PreparedStatement, ele também cria o objeto CallableStatement, que seria usado para executar uma chamada para um procedimento armazenado do banco de dados.
Criação do objeto CallableStatement
Suponha que você precise executar o seguinte procedimento armazenado Oracle -
CREATE OR REPLACE PROCEDURE getEmpName
(EMP_ID IN NUMBER, EMP_FIRST OUT VARCHAR) AS
BEGIN
SELECT first INTO EMP_FIRST
FROM Employees
WHERE ID = EMP_ID;
END;
NOTE: O procedimento armazenado acima foi escrito para Oracle, mas estamos trabalhando com banco de dados MySQL, portanto, vamos escrever o mesmo procedimento armazenado para MySQL da seguinte forma para criá-lo no banco de dados EMP -
DELIMITER $$
DROP PROCEDURE IF EXISTS `EMP`.`getEmpName` $$
CREATE PROCEDURE `EMP`.`getEmpName`
(IN EMP_ID INT, OUT EMP_FIRST VARCHAR(255))
BEGIN
SELECT first INTO EMP_FIRST
FROM Employees
WHERE ID = EMP_ID;
END $$
DELIMITER ;
Existem três tipos de parâmetros: IN, OUT e INOUT. O objeto PreparedStatement usa apenas o parâmetro IN. O objeto CallableStatement pode usar todos os três.
Aqui estão as definições de cada -
Parâmetro | Descrição |
---|---|
DENTRO | Um parâmetro cujo valor é desconhecido quando a instrução SQL é criada. Você associa valores a parâmetros IN com os métodos setXXX (). |
FORA | Um parâmetro cujo valor é fornecido pela instrução SQL que ele retorna. Você recupera valores dos parâmetros OUT com os métodos getXXX (). |
INOUT | Um parâmetro que fornece valores de entrada e saída. Você vincula variáveis com os métodos setXXX () e recupera valores com os métodos getXXX (). |
O seguinte snippet de código mostra como empregar o Connection.prepareCall() método para instanciar um CallableStatement objeto baseado no procedimento armazenado anterior -
CallableStatement cstmt = null;
try {
String SQL = "{call getEmpName (?, ?)}";
cstmt = conn.prepareCall (SQL);
. . .
}
catch (SQLException e) {
. . .
}
finally {
. . .
}
A variável String SQL representa o procedimento armazenado, com espaços reservados para parâmetros.
Usar os objetos CallableStatement é muito semelhante ao usar os objetos PreparedStatement. Você deve vincular valores a todos os parâmetros antes de executar a instrução ou receberá uma SQLException.
Se você tiver parâmetros IN, apenas siga as mesmas regras e técnicas que se aplicam a um objeto PreparedStatement; use o método setXXX () que corresponde ao tipo de dados Java que você está associando.
Ao usar os parâmetros OUT e INOUT, você deve empregar um método CallableStatement adicional, registerOutParameter (). O método registerOutParameter () vincula o tipo de dados JDBC ao tipo de dados que o procedimento armazenado deve retornar.
Depois de chamar seu procedimento armazenado, você recupera o valor do parâmetro OUT com o método getXXX () apropriado. Este método converte o valor recuperado do tipo SQL em um tipo de dados Java.
Fechando objeto CallableStatement
Assim como você fecha outro objeto Statement, pelo mesmo motivo você também deve fechar o objeto CallableStatement.
Uma chamada simples para o método close () fará o trabalho. Se você fechar o objeto Connection primeiro, ele também fechará o objeto CallableStatement. No entanto, você deve sempre fechar explicitamente o objeto CallableStatement para garantir a limpeza adequada.
CallableStatement cstmt = null;
try {
String SQL = "{call getEmpName (?, ?)}";
cstmt = conn.prepareCall (SQL);
. . .
}
catch (SQLException e) {
. . .
}
finally {
cstmt.close();
}
Para um melhor entendimento, sugiro estudar Callable - Example Code .