preparedStatement
need the support from DBMS.
if the sql has been compiled, the DB will cache it. When the same one appears again, just send the parameters to complete the cached sql.
prepareStatement
has three advantages:
make the code more clearly so you can read it easier.
improve the performance as far as possible. redue the compile time.
most important, it makes the sql more secure. if your sql is like this below:
String sql = "select * from users where userid = " + userid; // use statement
and someone give it a userid value like
userid = "1;delete users;";
the statement will execute the sql as
"select * from users where userid=1;"
"delete users;"
it is a very dangerouse operation for a database if the operator really has the right to do this.
if we use preparestatement
String sql = "select * from users where userid = ?"; // use preparestatement
the database will compile the sql as "select * from users where userid = '
?'
" and wait for the parameter "?" which means the sql will be execute like this
"select * from users where userid = '1;delete users;' ;" // of course, it will select 0 column.
treat the parameter just like a string.
This is the Note in the Interface java.sql.Connection
Class. read it
/**
* Creates a <code>PreparedStatement</code> object for sending
* parameterized SQL statements to the database.
* <P>
* A SQL statement with or without IN parameters can be
* pre-compiled and stored in a <code>PreparedStatement</code> object. This
* object can then be used to efficiently execute this statement
* multiple times.
*
* <P><B>Note:</B> This method is optimized for handling
* parametric SQL statements that benefit from precompilation. If
* the driver supports precompilation,
* the method <code>prepareStatement</code> will send
* the statement to the database for precompilation. Some drivers
* may not support precompilation. In this case, the statement may
* not be sent to the database until the <code>PreparedStatement</code>
* object is executed. This has no direct effect on users; however, it does
* affect which methods throw certain <code>SQLException</code> objects.
* <P>
* Result sets created using the returned <code>PreparedStatement</code>
* object will by default be type <code>TYPE_FORWARD_ONLY</code>
* and have a concurrency level of <code>CONCUR_READ_ONLY</code>.
* The holdability of the created result sets can be determined by
* calling {@link #getHoldability}.
*
* @param sql an SQL statement that may contain one or more '?' IN
* parameter placeholders
* @return a new default <code>PreparedStatement</code> object containing the
* pre-compiled SQL statement
* @exception SQLException if a database access error occurs
* or this method is called on a closed connection
*/
PreparedStatement prepareStatement(String sql)
throws SQLException;