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或实现缺陷吧!!!