executeupdate - preparedstatement java parameters
ParĂ¡metros nombrados en JDBC (6)
JDBC no admite parámetros con nombre. A menos que esté obligado a usar JDBC simple (lo que causa dolor, déjeme que lo diga), sugeriría usar Springs Excellent JDBCTemplate que puede usarse sin todo el Contenedor IoC.
NamedParameterJDBCTemplate admite parámetros con nombre, puede usarlos así:
NamedParameterJdbcTemplate jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
MapSqlParameterSource paramSource = new MapSqlParameterSource();
paramSource.addValue("name", name);
paramSource.addValue("city", city);
jdbcTemplate.queryForRowSet("SELECT * FROM customers WHERE name = :name AND city = :city", paramSource);
¿Hay parámetros nombrados en JDBC en lugar de los posicionales, como @name
, @city
en la consulta de ADO.NET a continuación?
select * from customers where name=@name and city = @city
No puede usar parámetros con nombre en JDBC. Podría intentar usar Spring framework, ya que tiene algunas extensiones que permiten el uso de parámetros con nombre en las consultas.
Normal vainilla JDBC no admite parámetros con nombre.
Si está utilizando DB2, utilice clases de DB2 directamente:
Para evitar incluir un gran marco, creo que una simple clase casera puede hacer el truco.
Ejemplo de clase para manejar parámetros con nombre:
public class NamedParamStatement {
public NamedParamStatement(Connection conn, String sql) throws SQLException {
int pos;
while((pos = sql.indexOf(":")) != -1) {
int end = sql.substring(pos).indexOf(" ");
if (end == -1)
end = sql.length();
else
end += pos;
fields.add(sql.substring(pos+1,end));
sql = sql.substring(0, pos) + "?" + sql.substring(end);
}
prepStmt = conn.prepareStatement(sql);
}
public PreparedStatement getPreparedStatement() {
return prepStmt;
}
public ResultSet executeQuery() throws SQLException {
return prepStmt.executeQuery();
}
public void close() throws SQLException {
prepStmt.close();
}
public void setInt(String name, int value) throws SQLException {
prepStmt.setInt(getIndex(name), value);
}
private int getIndex(String name) {
return fields.indexOf(name)+1;
}
private PreparedStatement prepStmt;
private List<String> fields = new ArrayList<String>();
}
Ejemplo de llamar a la clase:
String sql;
sql = "SELECT id, Name, Age, TS FROM TestTable WHERE Age < :age OR id = :id";
NamedParamStatement stmt = new NamedParamStatement(conn, sql);
stmt.setInt("age", 35);
stmt.setInt("id", 2);
ResultSet rs = stmt.executeQuery();
Tenga en cuenta que el ejemplo simple anterior no se maneja con el parámetro nombrado dos veces. Tampoco lo maneja usando: firmar dentro de comillas.
Terminé creando mi propio contenedor.
en el que primero esterilicé el valor que estaba ligado (puedes encontrar ejemplos en Google)
Luego usé el método
String.replace()
Java para reemplazar el placeHolders.
La mayor caída es que debe asegurarse de que la variable sea segura para el enlace.
Editar: ahora solo uso Spring''s Hibernate, mucho mejor
Vanilla JDBC solo admite parámetros nombrados en un CallableStatement
(por ejemplo, setString("name", name)
), e incluso entonces, sospecho que la implementación del procedimiento almacenado subyacente debe ser compatible.
Un ejemplo de cómo usar parámetros con nombre:
//uss Sybase ASE sysobjects table...adjust for your RDBMS
stmt = conn.prepareCall("create procedure p1 (@id int = null, @name varchar(255) = null) as begin "
+ "if @id is not null "
+ "select * from sysobjects where id = @id "
+ "else if @name is not null "
+ "select * from sysobjects where name = @name "
+ " end");
stmt.execute();
//call the proc using one of the 2 optional params
stmt = conn.prepareCall("{call p1 ?}");
stmt.setInt("@id", 10);
ResultSet rs = stmt.executeQuery();
while (rs.next())
{
System.out.println(rs.getString(1));
}
//use the other optional param
stmt = conn.prepareCall("{call p1 ?}");
stmt.setString("@name", "sysprocedures");
rs = stmt.executeQuery();
while (rs.next())
{
System.out.println(rs.getString(1));
}