首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >聊聊如何获取PreparedStatement的参数

聊聊如何获取PreparedStatement的参数

原创
作者头像
code4it
发布于 2023-09-06 01:27:25
发布于 2023-09-06 01:27:25
36600
代码可运行
举报
文章被收录于专栏:码匠的流水账码匠的流水账
运行总次数:0
代码可运行

本文主要研究一下如何获取PreparedStatement的参数

PreparedStatement

java/sql/PreparedStatement.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface PreparedStatement extends Statement {

	 void setNull(int parameterIndex, int sqlType) throws SQLException;

	 void setBoolean(int parameterIndex, boolean x) throws SQLException;

	 void setInt(int parameterIndex, int x) throws SQLException;

	 void setLong(int parameterIndex, long x) throws SQLException;

	 //......

	default void setObject(int parameterIndex, Object x, SQLType targetSqlType,
             int scaleOrLength) throws SQLException {
        throw new SQLFeatureNotSupportedException("setObject not implemented");
    }

    default void setObject(int parameterIndex, Object x, SQLType targetSqlType)
      throws SQLException {
        throw new SQLFeatureNotSupportedException("setObject not implemented");
    }

    /**
     * Retrieves the number, types and properties of this
     * <code>PreparedStatement</code> object's parameters.
     *
     * @return a <code>ParameterMetaData</code> object that contains information
     *         about the number, types and properties for each
     *  parameter marker of this <code>PreparedStatement</code> object
     * @exception SQLException if a database access error occurs or
     * this method is called on a closed <code>PreparedStatement</code>
     * @see ParameterMetaData
     * @since 1.4
     */
    ParameterMetaData getParameterMetaData() throws SQLException;
}

PreparedStatement继承了Statement接口,它主要是多定义了一系列的set方法,但是没有定义get方法,只是定义了getParameterMetaData方法返回ParameterMetaData

ParameterMetaData

java/sql/ParameterMetaData.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface ParameterMetaData extends Wrapper {

    /**
     * Retrieves the number of parameters in the <code>PreparedStatement</code>
     * object for which this <code>ParameterMetaData</code> object contains
     * information.
     *
     * @return the number of parameters
     * @exception SQLException if a database access error occurs
     * @since 1.4
     */
    int getParameterCount() throws SQLException;

    /**
     * Retrieves whether null values are allowed in the designated parameter.
     *
     * @param param the first parameter is 1, the second is 2, ...
     * @return the nullability status of the given parameter; one of
     *        <code>ParameterMetaData.parameterNoNulls</code>,
     *        <code>ParameterMetaData.parameterNullable</code>, or
     *        <code>ParameterMetaData.parameterNullableUnknown</code>
     * @exception SQLException if a database access error occurs
     * @since 1.4
     */
    int isNullable(int param) throws SQLException;

    /**
     * The constant indicating that a
     * parameter will not allow <code>NULL</code> values.
     */
    int parameterNoNulls = 0;

    /**
     * The constant indicating that a
     * parameter will allow <code>NULL</code> values.
     */
    int parameterNullable = 1;

    /**
     * The constant indicating that the
     * nullability of a parameter is unknown.
     */
    int parameterNullableUnknown = 2;

    /**
     * Retrieves whether values for the designated parameter can be signed numbers.
     *
     * @param param the first parameter is 1, the second is 2, ...
     * @return <code>true</code> if so; <code>false</code> otherwise
     * @exception SQLException if a database access error occurs
     * @since 1.4
     */
    boolean isSigned(int param) throws SQLException;

    /**
     * Retrieves the designated parameter's specified column size.
     *
     * <P>The returned value represents the maximum column size for the given parameter.
     * For numeric data, this is the maximum precision.  For character data, this is the length in characters.
     * For datetime datatypes, this is the length in characters of the String representation (assuming the
     * maximum allowed precision of the fractional seconds component). For binary data, this is the length in bytes.  For the ROWID datatype,
     * this is the length in bytes. 0 is returned for data types where the
     * column size is not applicable.
     *
     * @param param the first parameter is 1, the second is 2, ...
     * @return precision
     * @exception SQLException if a database access error occurs
     * @since 1.4
     */
    int getPrecision(int param) throws SQLException;

    /**
     * Retrieves the designated parameter's number of digits to right of the decimal point.
     * 0 is returned for data types where the scale is not applicable.
     *
     * @param param the first parameter is 1, the second is 2, ...
     * @return scale
     * @exception SQLException if a database access error occurs
     * @since 1.4
     */
    int getScale(int param) throws SQLException;

    /**
     * Retrieves the designated parameter's SQL type.
     *
     * @param param the first parameter is 1, the second is 2, ...
     * @return SQL type from <code>java.sql.Types</code>
     * @exception SQLException if a database access error occurs
     * @since 1.4
     * @see Types
     */
    int getParameterType(int param) throws SQLException;

    /**
     * Retrieves the designated parameter's database-specific type name.
     *
     * @param param the first parameter is 1, the second is 2, ...
     * @return type the name used by the database. If the parameter type is
     * a user-defined type, then a fully-qualified type name is returned.
     * @exception SQLException if a database access error occurs
     * @since 1.4
     */
    String getParameterTypeName(int param) throws SQLException;


    /**
     * Retrieves the fully-qualified name of the Java class whose instances
     * should be passed to the method <code>PreparedStatement.setObject</code>.
     *
     * @param param the first parameter is 1, the second is 2, ...
     * @return the fully-qualified name of the class in the Java programming
     *         language that would be used by the method
     *         <code>PreparedStatement.setObject</code> to set the value
     *         in the specified parameter. This is the class name used
     *         for custom mapping.
     * @exception SQLException if a database access error occurs
     * @since 1.4
     */
    String getParameterClassName(int param) throws SQLException;

    /**
     * The constant indicating that the mode of the parameter is unknown.
     */
    int parameterModeUnknown = 0;

    /**
     * The constant indicating that the parameter's mode is IN.
     */
    int parameterModeIn = 1;

    /**
     * The constant indicating that the parameter's mode is INOUT.
     */
    int parameterModeInOut = 2;

    /**
     * The constant indicating that the parameter's mode is  OUT.
     */
    int parameterModeOut = 4;

    /**
     * Retrieves the designated parameter's mode.
     *
     * @param param the first parameter is 1, the second is 2, ...
     * @return mode of the parameter; one of
     *        <code>ParameterMetaData.parameterModeIn</code>,
     *        <code>ParameterMetaData.parameterModeOut</code>, or
     *        <code>ParameterMetaData.parameterModeInOut</code>
     *        <code>ParameterMetaData.parameterModeUnknown</code>.
     * @exception SQLException if a database access error occurs
     * @since 1.4
     */
    int getParameterMode(int param) throws SQLException;
}

ParameterMetaDatat提供了getParameterCount、getParameterType、getParameterTypeName、getParameterClassName、getParameterMode

com.mysql.jdbc.PreparedStatement

com/mysql/jdbc/PreparedStatement.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class PreparedStatement extends com.mysql.jdbc.StatementImpl implements
		java.sql.PreparedStatement {

	//......

	protected int parameterCount;

	protected MysqlParameterMetadata parameterMetaData;

	private InputStream[] parameterStreams = null;

	private byte[][] parameterValues = null;

	/**
	 * Only used by statement interceptors at the moment to
	 * provide introspection of bound values
	 */
	protected int[] parameterTypes = null;

	public ParameterBindings getParameterBindings() throws SQLException {
		synchronized (checkClosed()) {
			return new EmulatedPreparedStatementBindings();
		}
	}

	//......
}		

mysql的PreparedStatement实现定义了parameterCount、parameterMetaData、parameterStreams、parameterValues、parameterTypes属性,提供了getParameterBindings方法,返回的是EmulatedPreparedStatementBindings

ParameterBindings

com/mysql/jdbc/ParameterBindings.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface ParameterBindings {

	public abstract Array getArray(int parameterIndex) throws SQLException;

	public abstract InputStream getAsciiStream(int parameterIndex) throws SQLException;

	public abstract BigDecimal getBigDecimal(int parameterIndex) throws SQLException;

	public abstract InputStream getBinaryStream(int parameterIndex) throws SQLException;

	public abstract java.sql.Blob getBlob(int parameterIndex) throws SQLException;

	public abstract boolean getBoolean(int parameterIndex) throws SQLException;
	
	public abstract byte getByte(int parameterIndex) throws SQLException;

	public abstract byte[] getBytes(int parameterIndex) throws SQLException;

	public abstract Reader getCharacterStream(int parameterIndex) throws SQLException;

	public abstract Clob getClob(int parameterIndex) throws SQLException;
	
	public abstract Date getDate(int parameterIndex) throws SQLException;
	
	public abstract double getDouble(int parameterIndex) throws SQLException;

	public abstract float getFloat(int parameterIndex) throws SQLException;

	public abstract int getInt(int parameterIndex) throws SQLException;
	
	public abstract long getLong(int parameterIndex) throws SQLException;

	public abstract Reader getNCharacterStream(int parameterIndex) throws SQLException;
	
	public abstract Reader getNClob(int parameterIndex) throws SQLException;
	
	public abstract Object getObject(int parameterIndex) throws SQLException;

	public abstract Ref getRef(int parameterIndex) throws SQLException;

	public abstract short getShort(int parameterIndex) throws SQLException;

	public abstract String getString(int parameterIndex) throws SQLException;

	public abstract Time getTime(int parameterIndex) throws SQLException;

	public abstract Timestamp getTimestamp(int parameterIndex) throws SQLException;

	public abstract URL getURL(int parameterIndex) throws SQLException;

	public abstract boolean isNull(int parameterIndex) throws SQLException;
}

ParameterBindings定义了一系列的get方法

EmulatedPreparedStatementBindings

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	class EmulatedPreparedStatementBindings implements ParameterBindings {

		private ResultSetImpl bindingsAsRs;
		private boolean[] parameterIsNull;
		
		EmulatedPreparedStatementBindings() throws SQLException {
			List<ResultSetRow> rows = new ArrayList<ResultSetRow>();
			parameterIsNull = new boolean[parameterCount];
			System
					.arraycopy(isNull, 0, this.parameterIsNull, 0,
							parameterCount);
			byte[][] rowData = new byte[parameterCount][];
			Field[] typeMetadata = new Field[parameterCount];

			for (int i = 0; i < parameterCount; i++) {
				if (batchCommandIndex == -1)
					rowData[i] = getBytesRepresentation(i);
				else
					rowData[i] = getBytesRepresentationForBatch(i, batchCommandIndex);

				int charsetIndex = 0;

				if (parameterTypes[i] == Types.BINARY
						|| parameterTypes[i] == Types.BLOB) {
					charsetIndex = 63;
				} else {
					try {
						String mysqlEncodingName = CharsetMapping
								.getMysqlEncodingForJavaEncoding(connection
										.getEncoding(), connection);
						charsetIndex = CharsetMapping
								.getCharsetIndexForMysqlEncodingName(mysqlEncodingName);
					} catch (SQLException ex) {
						throw ex;
					} catch (RuntimeException ex) {
						SQLException sqlEx = SQLError.createSQLException(ex.toString(), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, null);
						sqlEx.initCause(ex);
						throw sqlEx;
					}
				}

				Field parameterMetadata = new Field(null, "parameter_"
						+ (i + 1), charsetIndex, parameterTypes[i],
						rowData[i].length);
				parameterMetadata.setConnection(connection);
				typeMetadata[i] = parameterMetadata;
			}

			rows.add(new ByteArrayRow(rowData, getExceptionInterceptor()));

			this.bindingsAsRs = new ResultSetImpl(connection.getCatalog(),
					typeMetadata, new RowDataStatic(rows), connection, null);
			this.bindingsAsRs.next();
		}

		//......
	}		

EmulatedPreparedStatementBindings实现了ParameterBindings接口,它主要是把参数组装到rowData,然后创建了RowDataStatic,构造ResultSetImpl这个对象来实现

小结

jdbc的PreparedStatement并未提供相应的get参数的方法,只能从driver的实现类去找,比如mysql的PreparedStatement实现提供了getParameterBindings方法,返回的是EmulatedPreparedStatementBindings,可以获取参数

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
可输出sql的PrepareStatement封装
1 import java.io.InputStream; 2 import java.io.Reader; 3 import java.net.URL; 4 import java.sql.Connection; 5 import java.sql.NClob; 6 import java.sql.ParameterMetaData; 7 import java.sql.PreparedStatement; 8 import java.sql.ResultS
WindWant
2020/09/11
8650
4. 自定义DBUtils
在上一章节,我们使用 Apache-DBUtils 实现了数据库的增删查改,的确使用起来很方便。但是除了方便之余,我们还要思考一下这个 Apache-DBUtils 是如何实现的。
Devops海洋的渔夫
2021/10/12
7700
JDBC框架
在实际的开发中,如果直接使用JDBC开发,是非常繁琐且麻烦的,所以现在的企业在开发web程序时,连接数据库一定会使用一些JDBC的框架。 在学习框架之前,得先掌握一些基础知识。
wangweijun
2020/01/21
4840
深入理解JDBC设计模式: DriverManager 解析
JDBC 是java中的一个数据连接技术,它提供了统一的 API 允许用户访问任何形式的表格数据,尤其是存储在关系数据库中的数据。
烂猪皮
2021/04/23
2.2K0
深入理解JDBC设计模式: DriverManager 解析
[JavaWeb]关于DBUtils中QueryRunner的一些解读.
前言: [本文属于原创分享文章, 转载请注明出处, 谢谢.] 前面已经有文章说了DBUtils的一些特性, 这里再来详细说下QueryRunner的一些内部实现, 写的有错误的地方还恳请大家指出.  QueryRunner类 QueryRunner中提供对sql语句操作的API 它主要有三个方法 query() 用于执行select   update() 用于执行insert/update/delete   batch() 批处理 1,Query语句 先来看下query的两种形式, 我们这里主要讲第一个
一枝花算不算浪漫
2018/05/18
2K0
开源组件:(3)dbutils
commons-dbutils 是 Apache 组织提供的一个开源JDBC工具类库,它是对JDBC的简单封装,学习成本极低,并且使用dbutils能极大简化jdbc编码的工作量,同时也不会影响程序的性能。因此dbutils成为很多不喜欢hibernate的公司的首选。
py3study
2020/01/06
6440
聊聊mysql jdbc的prepareStatement
mysql-connector-java-5.1.21-sources.jar!/com/mysql/jdbc/ConnectionImpl.java
code4it
2023/09/04
4360
Java PreparedStatement
Java PreparedStatement Hierarchy Java PreparedStatement层次结构
全栈程序员站长
2022/09/06
3620
Java PreparedStatement
数据库中间件 Sharding-JDBC 源码分析 —— JDBC实现与读写分离
本文主要基于 Sharding-JDBC 1.5.0 正式版 1. 概述 2. unspported 包 3. adapter 包 3.1 WrapperAdapter 3.2 AbstractDataSourceAdapter 3.3 AbstractConnectionAdapter 3.4 AbstractStatementAdapter 3.5 AbstractPreparedStatementAdapter 3.6 AbstractResultSetAdapter 4. 插入流程 5. 查询流程
芋道源码
2018/03/02
1.6K0
数据库中间件 Sharding-JDBC 源码分析 —— JDBC实现与读写分离
聊聊ShardingSphere是怎么进行sql重写的
org/apache/shardingsphere/driver/jdbc/core/connection/ShardingSphereConnection.java
code4it
2023/09/05
4230
聊聊flink的JDBCOutputFormat
flink-jdbc_2.11-1.7.0-sources.jar!/org/apache/flink/api/java/io/jdbc/JDBCOutputFormat.java
code4it
2018/12/04
2.2K0
聊聊flink的JDBCOutputFormat
JDBC基础入门(2)
其他关于C3P0的详细内容, 可参考C3P0主页. HikariCP HikariCP是另一款高性能/”零开销”/高品质的数据库连接池,据测试,其性能优于C3P0(详细信息可参考号称性能最好的JDBC连接池:HikariCP),但国内HikariCP资料不多,其项目主页为https://github.com/brettwooldridge/HikariCP,使用HikariCP需要在pom.xml中添加如下依赖: <dependency> <groupId>com.zaxxer</groupId>
Java帮帮
2018/03/16
6200
JDBC 详解
JDBC(Java Database Connectivety),主要是用来连接数和操作数据库的API,本片文章基于JDBC4.2。
代码拾遗
2018/07/24
6610
你不知道的PreparedStatement预编译[通俗易懂]
大家好,又见面了,我是你们的朋友全栈君。 大家都知道,Mybatis内置参数,形如#{xxx}的,均采用了sql预编译的形式,大致知道mybatis底层使用PreparedStatement,过程是
全栈程序员站长
2022/09/02
9110
聊聊mysql jdbc的queryTimeout及next方法
本文主要介绍一下mysql jdbc statement的queryTimeout及resultSet的next方法
code4it
2018/09/17
1.8K0
【死磕Sharding-jdbc】---最大努力型事务
在分布式数据库的场景下,相信对于该数据库的操作最终一定可以成功,所以通过最大努力反复尝试送达操作。
用户1655470
2018/07/24
5760
【死磕Sharding-jdbc】---最大努力型事务
数据库中间件 Sharding-JDBC 源码分析 —— 事务(一)之BED
本文主要基于 Sharding-JDBC 1.5.0 正式版 1. 概述 2. 最大努力送达型 3. 柔性事务管理器 3.3.1 创建柔性事务 3.1 概念 3.2 柔性事务配置 3.3 柔性事务 4. 事务日志存储器 4.1 #add() 4.2 #remove() 4.3 #findEligibleTransactionLogs() 4.4 #increaseAsyncDeliveryTryTimes() 4.5 #processData() 5. 最大努力送达型事务监听器 6. 最大努力送达型异步作业
芋道源码
2018/03/02
1.7K0
数据库中间件 Sharding-JDBC 源码分析 —— 事务(一)之BED
java.sql.SQLException: 索引中丢失 IN或OUT 参数::x
使用JDBC时,会有这么一个错误:java.sql.SQLException: 索引中丢失 IN或OUT 参数::x
bisal
2019/01/29
3.3K0
java调用存储过程(stored procedures)的HelloWorld例子
1.java调用存储过程(stored procedures)的HelloWorld程序
马克java社区
2021/05/12
1.1K0
beanutils工具类_beanutils.copyproperties忽略null
BeanUtils工具是一种方便我们对JavaBean进行操作的工具,是Apache组织下的产品。
全栈程序员站长
2022/09/20
8740
相关推荐
可输出sql的PrepareStatement封装
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档