ParameterMetaData用于获取关于PreparedStatement对象中每个参数标记的类型和属性信息的对象。对于某些查询和驱动程序的实现,由ParameterMetaData对象返回的数据在PreparedStatement执行前可能不可用。 但是在使用MySQL通过ParameterMetaData获取关于PreparedStatement参数信息时抛出了如下异常信息:java.sql.SQLException: Parameter metadata not available for the given statement
java代码如下:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import com.bug315.C;
/**
* 测试ParameterMetaData类的功能
* @date 2016年4月4日10:26:21
*/
public class ParameterMetaDataTest {
public static void main(String[] args) throws Exception {
Class.forName(C.DRIVER);
/**
* 旧地址为“jdbc:mysql://localhost:3306/java_jdbc”,
* 由于MySQL的ParameterMetaData获取参数参数元数据信息失败,因此需要添加
* generateSimpleParameterMetadata=true选项,默认该选项为false;
* 详细信息见数据库驱动说明信息。
*/
String url = C.URL + "?generateSimpleParameterMetadata=true";
Connection conn = DriverManager.getConnection(url, C.USERNAME, C.PASSWORD);
StringBuffer sql = new StringBuffer();
sql.append("SELECT n_id,c_name,n_age,c_phone,n_salary,c_email");
sql.append(" FROM t_user WHERE n_id=? AND c_name=? AND n_age=?");
PreparedStatement ps = conn.prepareStatement( sql.toString() );
System.out.println( ps );
// 获取参数元信息
ParameterMetaData pm = ps.getParameterMetaData();
int count = pm.getParameterCount();
System.out.println("getParameterCount = " + count);
for (int i = 1; i <= count; i ++ ) {
System.out.println("getParameterClassName=" + pm.getParameterClassName(i) );
System.out.println("getParameterMode=" + pm.getParameterMode(i) );
System.out.println("getParameterType=" + pm.getParameterType(i) );
System.out.println("getParameterTypeName=" + pm.getParameterTypeName(i) );
System.out.println("getPrecision=" + pm.getPrecision(i) );
System.out.println("getScale=" + pm.getScale(i) );
System.out.println("isNullable=" + pm.isNullable(i) );
System.out.println("isSigned=" + pm.isSigned(i) );
System.out.println();
}
ps.setInt(1, 1);
ps.setString(2, "zhangsan");
ps.setInt(3, 27);
ResultSet rs = ps.executeQuery();
// 输出结果信息
while ( rs.next() ) {
int index = 1;
StringBuffer buffer = new StringBuffer();
buffer.append("n_id=").append( rs.getInt(index++) )
.append(", c_name=").append( rs.getString(index++) )
.append(", n_age=").append( rs.getInt(index++) )
.append(", c_phone=").append( rs.getString(index++) )
.append(", n_salary=").append( rs.getDouble(index++) )
.append(", c_email=").append( rs.getString(index++) );
System.out.println( buffer.toString() );
}
}
}在默认情况下generateSimpleParameterMetadata=false,因此我们使用ParameterMetaData获取PreparedStatment参数信息时抛出了异常。因此我们需要将generateSimpleParameterMetadata设置为true。下面是MySQL驱动程序给出generateSimpleParameterMetadata属性的说明:
generateSimpleParameterMetadata
Should the driver generate simplified parameter metadata for PreparedStatements when no metadata is available either because the server couldn't support preparing the statement, or server-side prepared statements are disabled?
Default: false
Since version: 5.0.5
但是,即使我们设置了generateSimpleParameterMetadata=true,但是isNullable()方法还是将抛出异常,这就可能是MySQL驱动程序的Bug或实现缺陷吧!!!