java jdbc 命名参数_支持命名参数的PreparedStatement

PreparedStatement语法存在的问题

PreparedStatement的问题来源于它的参数的语法,PreparedStatement语句的参数是匿名并被通过索引访问,如下代码所示:

PreparedStatement p = con.prepareStatement("select * from people where

(first_name = ? or last_name = ?) and address = ?");

p.setString(1, name);

p.setString(2, name);

p.setString(3, address);

对于一两个小的查询来说,这不是问题,但是对于大量参数的查询,跟踪索引就会变得困难。开发者必须小心翼翼的阅读SQL语句并查找出对应的参数索引,如果一个参数被插入或被删除,所有的索引就要被重新命名,很显然,当这个被插入或删除的参数在最开始,而后面还有更多的参数的时候,或者查询被重新组织了,这两种情况都会导致很多麻烦。

解决方法?(Workarounds)

有一个方法可以解决重新命名索引,那就是使用一个计数器来跟踪索引,如下代码所示:

PreparedStatement p = con.prepareStatement("select * from people where

(first_name = ? or last_name = ?) and address = ?");

int i = 1;

p.setString(i++, name);

p.setString(i++, name);

p.setString(i++, address);

这种方法对于某个参数被插入或者删除的情况来说,有很好的效果,但是代码依然可读性差,而且程序员依然要注意确保参数的顺序。

NamedParameterStatement

现在我们来看看NamedParameterStatement这个类,这个类和PreparedStatement的基本相同,除了一点,那就是不是用问号?来顶替索引,而是用一个变量来顶替索引,如下面的代码所示:

String query = "select * from people where (first_name = :name or last_name

= :name) and address = :address");

NamedParameterStatement p = new NamedParameterStatement(con, query);

p.setString("name", name);

p.setString("address", address);

这个类的内幕就是,NamedParameterStatement类做了一个转换,它使用HashMap将SQL语句种对应的变量转换成问号,然后再创建一个对应的PreparedStatement语句,并且保持了对应变量和索引的映射关系,这两个类是兼容的,所以你可以分别加以利用。

论性能

两者的性能的差别在于NamedParameterStatement多了一个转换的过程,但这个过程所消耗的性能是非常之小,经过本机的测试,执行一条简单的查询表的记录的语句,PreparedStatement花了332毫秒,而NamedParameterStatement则花了352毫秒。在加入缓存之后,已经没有任何区别。

总结

NamedParameterStatement作为PreparedStatement的代替是高效而且无需配置的,同时它的简便的接口也提高了程序员的效率,或者更重要的是,由于代码的可读性增强,维护会变得更加轻松。

附上代码:

import java.io.InputStream;

import java.io.Reader;

import java.math.BigDecimal;

import java.net.URL;

import java.sql.*;

import java.sql.Date;

import java.util.*;

/**

* This class wraps around a {@link PreparedStatement} and allows the programmer to set parameters by name instead

* of by index. This eliminates any confusion as to which parameter index represents what. This also means that

* rearranging the SQL statement or adding a parameter doesn't involve renumbering your indices.

* Code such as this:

*

*

* Connection conn = getConnection();

* String sql = "select * from my_table where name=? or address=?";

* PreparedStatement p = conn.prepareStatement(sql);

* p.setString(1, "bob");

* p.setString(2, "123");

* ResultSet rs = p.executeQuery();

*

*

* Can be replaced with:

*

*

* Connection conn = getConnection();

* String sql = "select * from my_table where name=:name or address=:address";

* NamedParameterStatement p = new NamedParameterStatement(conn, sql);

* p.setString("name", "bob");

* p.setString("address", "123");

* ResultSet rs = p.executeQuery();

*

*/

public class NamedParameterStatement extends PreparedStatementWrapper {

private static final HashMap>> nameIndexCache = new HashMap>>();

private static final HashMap parsedSqlCache = new HashMap();

private final String parsedSql;

private final Map> nameIndexMap;

/**

* Creates a NamedParameterStatement. Wraps a call to

* c.{@link Connection#prepareStatement(java.lang.String) prepareStatement}.

* @param conn the database connection

* @param sql the parameterized sql

* @throws SQLException if the statement could not be created

*/

public NamedParameterStatement(Connection conn, String sql) throws SQLException {

if (nameIndexCache.containsKey(sql)) {

nameIndexMap = nameIndexCache.get(sql);

parsedSql = parsedSqlCache.get(sql);

} else {

nameIndexMap = new HashMap>();

parsedSql = parseNamedSql(sql, nameIndexMap);

nameIndexCache.put(sql, nameIndexMap);

parsedSqlCache.put(sql, parsedSql);

}

ps = conn.prepareStatement(parsedSql);

}

/**

* Returns the indexes for a parameter.

* @param name parameter name

* @return parameter indexes

* @throws IllegalArgumentException if the parameter does not exist

*/

private List getIndexes(String name) {

List indexes = nameIndexMap.get(name);

if (indexes == null) {

throw new IllegalArgumentException("Parameter not found: " + name);

}

return indexes;

}

/**

* Parses a sql with named parameters. The parameter-index mappings

* are put into the map, and the parsed sql is returned.

* @param sql sql with named parameters

* @return the parsed sql

*/

private static String parseNamedSql(String sql, Map> nameIndexMap) {

// I was originally using regular expressions, but they didn't work well for ignoring

// parameter-like strings inside quotes.

int length = sql.length();

StringBuffer parsedSql = new StringBuffer(length);

boolean inSingleQuote = false;

boolean inDoubleQuote = false;

int index = 1;

for (int i = 0; i < length; i++) {

char c = sql.charAt(i);

if (inSingleQuote) {

if (c == '\'') {

inSingleQuote = false;

}

} else if (inDoubleQuote) {

if (c == '"') {

inDoubleQuote = false;

}

} else {

if (c == '\'') {

inSingleQuote = true;

} else if (c == '"') {

inDoubleQuote = true;

} else if (c == ':' && i + 1 < length && Character.isJavaIdentifierStart(sql.charAt(i + 1))) {

int j = i + 2;

while (j < length && Character.isJavaIdentifierPart(sql.charAt(j))) {

j++;

}

String name = sql.substring(i + 1, j);

c = '?'; // replace the parameter with a question mark

i += name.length(); // skip past the end if the parameter

List indexList = nameIndexMap.get(name);

if (indexList == null) {

indexList = new LinkedList();

nameIndexMap.put(name, indexList);

}

indexList.add(index);

index++;

}

}

parsedSql.append(c);

}

return parsedSql.toString();

}

public void setArray(String name, Array value) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setArray(index, value);

}

}

public void setAsciiStream(String name, InputStream value) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setAsciiStream(index, value);

}

}

public void setAsciiStream(String name, InputStream value, int length) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setAsciiStream(index, value, length);

}

}

public void setBigDecimal(String name, BigDecimal value) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setBigDecimal(index, value);

}

}

public void setBinaryStream(String name, InputStream value) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setBinaryStream(index, value);

}

}

public void setBinaryStream(String name, InputStream value, int length) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setBinaryStream(index, value, length);

}

}

public void setBinaryStream(String name, InputStream value, long length) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setBinaryStream(index, value, length);

}

}

public void setBlob(String name, Blob value) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setBlob(index, value);

}

}

public void setBlob(String name, InputStream value) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setBlob(index, value);

}

}

public void setBlob(String name, InputStream value, long length) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setBlob(index, value, length);

}

}

public void setBoolean(String name, boolean value) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setBoolean(index, value);

}

}

public void setByte(String name, byte value) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setByte(index, value);

}

}

public void setBytes(String name, byte[] value) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setBytes(index, value);

}

}

public void setCharacterStream(String name, Reader value) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setCharacterStream(index, value);

}

}

public void setCharacterStream(String name, Reader value, int length) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setCharacterStream(index, value, length);

}

}

public void setCharacterStream(String name, Reader value, long length) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setCharacterStream(index, value, length);

}

}

public void setClob(String name, Clob value) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setClob(index, value);

}

}

public void setClob(String name, Reader value) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setClob(index, value);

}

}

public void setClob(String name, Reader value, long length) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setClob(index, value, length);

}

}

public void setDate(String name, Date value) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setDate(index, value);

}

}

public void setDate(String name, Date value, Calendar cal) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setDate(index, value, cal);

}

}

public void setDouble(String name, double value) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setDouble(index, value);

}

}

public void setFloat(String name, float value) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setFloat(index, value);

}

}

public void setInt(String name, int value) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setInt(index, value);

}

}

public void setLong(String name, long value) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setLong(index, value);

}

}

public void setNCharacterStream(String name, Reader value) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setNCharacterStream(index, value);

}

}

public void setNCharacterStream(String name, Reader value, long length) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setNCharacterStream(index, value, length);

}

}

public void setNClob(String name, NClob value) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setNClob(index, value);

}

}

public void setNClob(String name, Reader value) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setNClob(index, value);

}

}

public void setNClob(String name, Reader value, long length) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setNClob(index, value, length);

}

}

public void setNString(String name, String value) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setNString(index, value);

}

}

public void setNull(String name, int sqlType) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setNull(index, sqlType);

}

}

public void setObject(String name, Object value) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setObject(index, value);

}

}

public void setObject(String name, Object value, int targetSqlType) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setObject(index, value, targetSqlType);

}

}

public void setObject(String name, Object value, int targetSqlType, int scaleOrLength) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setObject(index, value, targetSqlType, scaleOrLength);

}

}

public void setRef(String name, Ref value) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setRef(index, value);

}

}

public void setRowId(String name, RowId value) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setRowId(index, value);

}

}

public void setShort(String name, short value) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setShort(index, value);

}

}

public void setSQLXML(String name, SQLXML value) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setSQLXML(index, value);

}

}

public void setString(String name, String value) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setString(index, value);

}

}

public void setTime(String name, Time value) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setTime(index, value);

}

}

public void setTime(String name, Time value, Calendar cal) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setTime(index, value, cal);

}

}

public void setTimestamp(String name, Timestamp value) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setTimestamp(index, value);

}

}

public void setTimestamp(String name, Timestamp value, Calendar cal) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setTimestamp(index, value, cal);

}

}

@SuppressWarnings("deprecation")

public void setUnicodeStream(String name, InputStream value, int length) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setUnicodeStream(index, value, length);

}

}

public void setURL(String name, URL value) throws SQLException {

for (Integer index : getIndexes(name)) {

ps.setURL(index, value);

}

}

}

import java.io.InputStream;

import java.io.Reader;

import java.math.BigDecimal;

import java.net.URL;

import java.sql.*;

import java.sql.Date;

import java.util.*;

public class PreparedStatementWrapper implements PreparedStatement {

protected PreparedStatement ps;

@Override

public T unwrap(Class iface) throws SQLException {

return ps.unwrap(iface);

}

@Override

public ResultSet executeQuery(String sql) throws SQLException {

return ps.executeQuery(sql);

}

@Override

public ResultSet executeQuery() throws SQLException {

return ps.executeQuery();

}

@Override

public boolean isWrapperFor(Class> iface) throws SQLException {

return ps.isWrapperFor(iface);

}

@Override

public int executeUpdate(String sql) throws SQLException {

return ps.executeUpdate(sql);

}

@Override

public int executeUpdate() throws SQLException {

return ps.executeUpdate();

}

@Override

public void setNull(int parameterIndex, int sqlType) throws SQLException {

ps.setNull(parameterIndex, sqlType);

}

@Override

public void close() throws SQLException {

ps.close();

}

@Override

public int getMaxFieldSize() throws SQLException {

return ps.getMaxFieldSize();

}

@Override

public void setBoolean(int parameterIndex, boolean x) throws SQLException {

ps.setBoolean(parameterIndex, x);

}

@Override

public void setByte(int parameterIndex, byte x) throws SQLException {

ps.setByte(parameterIndex, x);

}

@Override

public void setMaxFieldSize(int max) throws SQLException {

ps.setMaxFieldSize(max);

}

@Override

public void setShort(int parameterIndex, short x) throws SQLException {

ps.setShort(parameterIndex, x);

}

@Override

public int getMaxRows() throws SQLException {

return ps.getMaxRows();

}

@Override

public void setInt(int parameterIndex, int x) throws SQLException {

ps.setInt(parameterIndex, x);

}

@Override

public void setMaxRows(int max) throws SQLException {

ps.setMaxRows(max);

}

@Override

public void setLong(int parameterIndex, long x) throws SQLException {

ps.setLong(parameterIndex, x);

}

@Override

public void setEscapeProcessing(boolean enable) throws SQLException {

ps.setEscapeProcessing(enable);

}

@Override

public void setFloat(int parameterIndex, float x) throws SQLException {

ps.setFloat(parameterIndex, x);

}

@Override

public void setDouble(int parameterIndex, double x) throws SQLException {

ps.setDouble(parameterIndex, x);

}

@Override

public int getQueryTimeout() throws SQLException {

return ps.getQueryTimeout();

}

@Override

public void setQueryTimeout(int seconds) throws SQLException {

ps.setQueryTimeout(seconds);

}

@Override

public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {

ps.setBigDecimal(parameterIndex, x);

}

@Override

public void setString(int parameterIndex, String x) throws SQLException {

ps.setString(parameterIndex, x);

}

@Override

public void setBytes(int parameterIndex, byte[] x) throws SQLException {

ps.setBytes(parameterIndex, x);

}

@Override

public void cancel() throws SQLException {

ps.cancel();

}

@Override

public SQLWarning getWarnings() throws SQLException {

return ps.getWarnings();

}

@Override

public void setDate(int parameterIndex, Date x) throws SQLException {

ps.setDate(parameterIndex, x);

}

@Override

public void setTime(int parameterIndex, Time x) throws SQLException {

ps.setTime(parameterIndex, x);

}

@Override

public void clearWarnings() throws SQLException {

ps.clearWarnings();

}

@Override

public void setCursorName(String name) throws SQLException {

ps.setCursorName(name);

}

@Override

public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {

ps.setTimestamp(parameterIndex, x);

}

@Override

public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException {

ps.setAsciiStream(parameterIndex, x, length);

}

@Override

public boolean execute(String sql) throws SQLException {

return ps.execute(sql);

}

@Override

@SuppressWarnings("deprecation")

public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException {

ps.setUnicodeStream(parameterIndex, x, length);

}

@Override

public ResultSet getResultSet() throws SQLException {

return ps.getResultSet();

}

@Override

public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException {

ps.setBinaryStream(parameterIndex, x, length);

}

@Override

public int getUpdateCount() throws SQLException {

return ps.getUpdateCount();

}

@Override

public boolean getMoreResults() throws SQLException {

return ps.getMoreResults();

}

@Override

public void clearParameters() throws SQLException {

ps.clearParameters();

}

@Override

public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {

ps.setObject(parameterIndex, x, targetSqlType);

}

@Override

public void setFetchDirection(int direction) throws SQLException {

ps.setFetchDirection(direction);

}

@Override

public int getFetchDirection() throws SQLException {

return ps.getFetchDirection();

}

@Override

public void setObject(int parameterIndex, Object x) throws SQLException {

ps.setObject(parameterIndex, x);

}

@Override

public void setFetchSize(int rows) throws SQLException {

ps.setFetchSize(rows);

}

@Override

public int getFetchSize() throws SQLException {

return ps.getFetchSize();

}

@Override

public int getResultSetConcurrency() throws SQLException {

return ps.getResultSetConcurrency();

}

@Override

public boolean execute() throws SQLException {

return ps.execute();

}

@Override

public int getResultSetType() throws SQLException {

return ps.getResultSetType();

}

@Override

public void addBatch(String sql) throws SQLException {

ps.addBatch(sql);

}

@Override

public void clearBatch() throws SQLException {

ps.clearBatch();

}

@Override

public void addBatch() throws SQLException {

ps.addBatch();

}

@Override

public int[] executeBatch() throws SQLException {

return ps.executeBatch();

}

@Override

public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException {

ps.setCharacterStream(parameterIndex, reader, length);

}

@Override

public void setRef(int parameterIndex, Ref x) throws SQLException {

ps.setRef(parameterIndex, x);

}

@Override

public void setBlob(int parameterIndex, Blob x) throws SQLException {

ps.setBlob(parameterIndex, x);

}

@Override

public void setClob(int parameterIndex, Clob x) throws SQLException {

ps.setClob(parameterIndex, x);

}

@Override

public Connection getConnection() throws SQLException {

return ps.getConnection();

}

@Override

public void setArray(int parameterIndex, Array x) throws SQLException {

ps.setArray(parameterIndex, x);

}

@Override

public ResultSetMetaData getMetaData() throws SQLException {

return ps.getMetaData();

}

@Override

public boolean getMoreResults(int current) throws SQLException {

return ps.getMoreResults(current);

}

@Override

public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException {

ps.setDate(parameterIndex, x, cal);

}

@Override

public ResultSet getGeneratedKeys() throws SQLException {

return ps.getGeneratedKeys();

}

@Override

public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException {

ps.setTime(parameterIndex, x, cal);

}

@Override

public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {

return ps.executeUpdate(sql, autoGeneratedKeys);

}

@Override

public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException {

ps.setTimestamp(parameterIndex, x, cal);

}

@Override

public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException {

ps.setNull(parameterIndex, sqlType, typeName);

}

@Override

public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {

return ps.executeUpdate(sql, columnIndexes);

}

@Override

public void setURL(int parameterIndex, URL x) throws SQLException {

ps.setURL(parameterIndex, x);

}

@Override

public int executeUpdate(String sql, String[] columnNames) throws SQLException {

return ps.executeUpdate(sql, columnNames);

}

@Override

public ParameterMetaData getParameterMetaData() throws SQLException {

return ps.getParameterMetaData();

}

@Override

public void setRowId(int parameterIndex, RowId x) throws SQLException {

ps.setRowId(parameterIndex, x);

}

@Override

public void setNString(int parameterIndex, String value) throws SQLException {

ps.setNString(parameterIndex, value);

}

@Override

public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {

return ps.execute(sql, autoGeneratedKeys);

}

@Override

public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException {

ps.setNCharacterStream(parameterIndex, value, length);

}

@Override

public void setNClob(int parameterIndex, NClob value) throws SQLException {

ps.setNClob(parameterIndex, value);

}

@Override

public void setClob(int parameterIndex, Reader reader, long length) throws SQLException {

ps.setClob(parameterIndex, reader, length);

}

@Override

public boolean execute(String sql, int[] columnIndexes) throws SQLException {

return ps.execute(sql, columnIndexes);

}

@Override

public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException {

ps.setBlob(parameterIndex, inputStream, length);

}

@Override

public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException {

ps.setNClob(parameterIndex, reader, length);

}

@Override

public boolean execute(String sql, String[] columnNames) throws SQLException {

return ps.execute(sql, columnNames);

}

@Override

public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {

ps.setSQLXML(parameterIndex, xmlObject);

}

@Override

public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) throws SQLException {

ps.setObject(parameterIndex, x, targetSqlType, scaleOrLength);

}

@Override

public int getResultSetHoldability() throws SQLException {

return ps.getResultSetHoldability();

}

@Override

public boolean isClosed() throws SQLException {

return ps.isClosed();

}

@Override

public void setPoolable(boolean poolable) throws SQLException {

ps.setPoolable(poolable);

}

@Override

public boolean isPoolable() throws SQLException {

return ps.isPoolable();

}

@Override

public void closeOnCompletion() throws SQLException {

ps.closeOnCompletion();

}

@Override

public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException {

ps.setAsciiStream(parameterIndex, x, length);

}

@Override

public boolean isCloseOnCompletion() throws SQLException {

return ps.isCloseOnCompletion();

}

@Override

public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException {

ps.setBinaryStream(parameterIndex, x, length);

}

@Override

public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException {

ps.setCharacterStream(parameterIndex, reader, length);

}

@Override

public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException {

ps.setAsciiStream(parameterIndex, x);

}

@Override

public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException {

ps.setBinaryStream(parameterIndex, x);

}

@Override

public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException {

ps.setCharacterStream(parameterIndex, reader);

}

@Override

public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {

ps.setNCharacterStream(parameterIndex, value);

}

@Override

public void setClob(int parameterIndex, Reader reader) throws SQLException {

ps.setClob(parameterIndex, reader);

}

@Override

public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException {

ps.setBlob(parameterIndex, inputStream);

}

@Override

public void setNClob(int parameterIndex, Reader reader) throws SQLException {

ps.setNClob(parameterIndex, reader);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
是的,你可以使用参数名占位符来代替问号占位符,以使代码更加可读。以下是一个使用参数名占位符的Java连接MySQL数据库的示例代码: ```java import java.sql.*; public class ConnectMySQL { public static void main(String[] args) { Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try { // 注册MySQL驱动 Class.forName("com.mysql.jdbc.Driver"); // 打开一个连接 String url = "jdbc:mysql://localhost:3306/test"; String user = "root"; String password = "123456"; conn = DriverManager.getConnection(url, user, password); // 预处理SQL语句 String sql = "SELECT * FROM student WHERE id=:id"; pstmt = conn.prepareStatement(sql); // 设置参数 pstmt.setInt("id", 1); // 执行查询操作 rs = pstmt.executeQuery(); // 处理结果集 while (rs.next()) { int id = rs.getInt("id"); String name = rs.getString("name"); int age = rs.getInt("age"); System.out.println("id: " + id + ", name: " + name + ", age: " + age); } // 关闭连接 rs.close(); pstmt.close(); conn.close(); } catch (Exception e) { e.printStackTrace(); } } } ``` 上述代码中,我们使用了命名参数占位符来代替问号占位符,以增加代码的可读性和可维护性。在预处理语句中,我们使用了冒号加参数名的格式来表示参数占位符,例如:":id"。在设置参数值时,我们调用了PreparedStatement对象的setXXX方法,并使用参数名来指定参数的值,例如:pstmt.setInt("id", 1)。最后,我们还需要在finally块中关闭连接、预处理语句和结果集等资源,以确保程序的稳定性和性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值