update preparedstatement parameter executeupdate example java jdbc named-parameters

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.



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.

  1. en el que primero esterilicé el valor que estaba ligado (puedes encontrar ejemplos en Google)

  2. 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)); }