preparestatement - ¿Cómo funciona PreparedStatement de Java?
preparedstatement java update (5)
Si tiene variables, use el ''?''
int temp = 75;
PreparedStatement pstmt = con.prepareStatement(
"UPDATE test SET num = ?, due = now() ");
pstmt.setInt(1, temp);
pstmt.executeUpdate():
Produce una declaración sql que se ve así:
UPDATE test SET num = 75, due = now();
Estoy planeando reemplazar objetos Statement repetidamente ejecutados con objetos PreparedStatement
para mejorar el rendimiento. Estoy usando argumentos como la función MySQL now()
y las variables de cadena.
La mayoría de las consultas de PreparedStatement
que he visto contenían valores constantes (como 10
y cadenas como "New York"
) como argumentos utilizados para el ?
en las consultas. ¿Cómo utilizaría funciones como now()
y variables como argumentos? ¿Es necesario usar el ?
s en las consultas en lugar de los valores reales? Estoy bastante confundido.
No tiene que usar marcadores de posición en un Estado Preparado. Algo como:
PreparedStatement stmt = con.prepareStatement("select sysdate from dual");
funcionaría bien Sin embargo, no puede usar un marcador de posición y luego enlazar una llamada a función. Algo como esto no se puede usar para llamar a la función sysdate:
PreparedStatement stmt = con.prepareStatement("select ? from dual");
stmt.setSomethingOrOther(1, "sysdate");
Si llama funciones integradas de su servidor SQL, utilice PreparedStatement .
Si llama a procedimientos almacenados que se han cargado en su servidor SQL, entonces use CallableStatement .
Use los signos de interrogación como marcadores de posición para los parámetros de función / procedimiento que está pasando y los valores de retorno de función que está recibiendo.
Desarrollé una función que le permite usar parámetros con nombre en sus consultas SQL:
private PreparedStatement generatePreparedStatement(String query, Map<String, Object> parameters) throws DatabaseException
{
String paramKey = "";
Object paramValue = null;
PreparedStatement statement = null;
Pattern paramRegex = null;
Matcher paramMatcher = null;
int paramIndex = 1;
try
{
//Create the condition
paramRegex = Pattern.compile("(:[//d//w_-]+)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
paramMatcher = paramRegex.matcher(query);
statement = this.m_Connection.prepareStatement(paramMatcher.replaceAll("?"),
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY,
ResultSet.HOLD_CURSORS_OVER_COMMIT);
//Check if there are parameters
paramMatcher = paramRegex.matcher(query);
while (paramMatcher.find())
{
paramKey = paramMatcher.group().substring(1);
if(parameters != null && parameters.containsKey(paramKey))
{
//Add the parameter
paramValue = parameters.get(paramKey);
if (paramValue instanceof Date)
{
statement.setDate(paramIndex, (java.sql.Date)paramValue);
}
else if (paramValue instanceof Double)
{
statement.setDouble(paramIndex, (Double)paramValue);
}
else if (paramValue instanceof Long)
{
statement.setLong(paramIndex, (Long)paramValue);
}
else if (paramValue instanceof Integer)
{
statement.setInt(paramIndex, (Integer)paramValue);
}
else if (paramValue instanceof Boolean)
{
statement.setBoolean(paramIndex, (Boolean)paramValue);
}
else
{
statement.setString(paramIndex, paramValue.toString());
}
}
else
{
throw new DatabaseException("The parameter ''" + paramKey + "'' doesn''t exists in the filter ''" + query + "''");
}
paramIndex++;
}
}
catch (SQLException l_ex)
{
throw new DatabaseException(tag.lib.common.ExceptionUtils.getFullMessage(l_ex));
}
return statement;
}
Puedes usarlo de esta manera:
Map<String, Object> pars = new HashMap<>();
pars.put("name", "O''Really");
String sql = "SELECT * FROM TABLE WHERE NAME = :name";
Si tiene una variable que proviene de la entrada del usuario, es esencial que use el? en lugar de concatenar las cuerdas. Los usuarios pueden ingresar una cadena maliciosamente, y si suelta la cadena directamente en SQL puede ejecutar un comando que no pretendía.
Me doy cuenta de que este es usado en exceso, pero lo dice perfectamente: