A PreparedStatement
declares the statement before it is executed, and allows for placeholders for parameters. This allows the statement to be prepared (and optimized) once on the server, and then reused with different sets of parameters.
The added benefit of the parameter placeholders, is that it provides protection against SQL injection. This is achieved either by sending the parameter values separately, or because the driver escapes values correctly as needed.
Placeholders in the query string need to be set by using the set*
methods:
String sql = "SELECT * FROM EMP WHERE JOB = ? AND SAL > ?";
//Create statement to make your operations
PreparedStatement statement = connection.prepareStatement(sql);
statement.setString(1, "MANAGER"); // String value
statement.setInt(2, 2850); // int value
Setting a null value can not be accomplished using for example the setInt
and setLong
methods, as these use primitive types (int
and long
) instead of objects (Integer
and Long
), and would cause a NullPointerException
to be thrown:
void setFloat(int parameterIndex, float x)
void setInt(int parameterIndex, int x)
void setLong(int parameterIndex, long x)
These cases can be handled by using setNull
.
setNull(int parameterIndex, int sqlType)
It is typed, so the second parameter has to be provided, see java.sql.Types
//setting a NULL for an integer value
statement.setNull(2, java.sql.Types.INTEGER);
LOBs require special objects to be used.
Clob longContent = connection.createClob();
Writer longContentWriter = longContent.setCharacterStream(1); // position: beginning
longContentWriter.write("This will be the content of the CLOB");
pstmt = connection.prepareStatement("INSERT INTO CLOB_TABLE(CLOB_VALUE) VALUES (?)");
pstmt.setClob(1, longContent);
set*
methods
SQLException
- ifparameterIndex
does not correspond to a parameter marker in the SQL statement; if a database access error occurs or this method is called on a closedPreparedStatement
SQLFeatureNotSupportedException
- if sqlType is aARRAY
,BLOB
,CLOB
,DATALINK
,JAVA_OBJECT
,NCHAR
,NCLOB
,NVARCHAR
,LONGNVARCHAR
,REF
,ROWID
,SQLXML
orSTRUCT
data type and the JDBC driver does not support this data type
This example shows how to create a prepared statement with an insert statement with parameters, set values to those parameters and then executing the statement.
Connection connection = ... // connection created earlier
try (PreparedStatement insert = connection.prepareStatement(
"insert into orders(id, customerid, totalvalue, comment) values (?, ?, ?, ?)")) {
//NOTE: Position indexes start at 1, not 0
insert.setInt(1, 1);
insert.setInt(2, 7934747);
insert.setBigDecimal(3, new BigDecimal("100.95"));
insert.setString(4, "quick delivery requested");
insert.executeUpdate();
}
The question marks (?
) in the insert statement are the parameter placeholders. They are positional parameters that are later referenced (using a 1-based index) using the setXXX
methods to set values to those parameters.
The use of try-with-resources ensures that the statement is closed and any resources in use for that statement are released.