Java JDBC类型转换(Firebird/Jaybird):在使用getter或updater ResultSet方



如果我能很好地理解(并测试一个示例JDBC代码;对Firebird使用Jaybird),即使使用适当的(=尊重类型映射)更新程序方法(例如ResultSet.updateString)或PreparedStatement参数,也会带来"转换异常"。

在实际使用结果集(例如运行更新程序方法)之前,是否可以测试实际的Java类型/值是否可以安全地转换为目标SQL数据类型?

"问题"只是单向的吗?也就是说,当从SQL转换回Java(使用getter方法)时,是否保证正确的getter方法永远不会失败(由于转换问题)?

我的例子(使用Jaybird 3.0.2、JDK1.8):

  • 我需要更新字段:NUMERIC(9,2)。相应的更新程序是:ResultSet.updateBigDecimal(int columnIndex, BigDecimal x)。如果我使用x = new BigDecimal("123456789.1234")(更大的精度和规模),我(逻辑上)会得到一个异常:线程"main"org.firebirdsql.jdbc.field.TypeConversionException中出现异常:转换为大小数时出错
  • 我需要更新字段:VARCHAR(5)。相应的更新程序为:ResultSet.updateString(int columnIndex, String x)。如果我使用x = "123456"(较长的字符串6>5),我(从逻辑上)会得到一个异常:线程"main"java.sql.DataTruncation:数据截断中的异常

除了尝试运行查询和捕获异常之外,是否有一些通用的优雅方法(不取决于特定类型)来检查实际的Java值/对象是否可以"保存"到特定的SQL字段?

我想检查数据编辑对话框中已经存在的值(在实际运行更新查询之前)。简单的测试"VALUE OK/NOT OK"就可以了(只知道目标SQL类型)。

我似乎很难找到我必须"逐个类型"检查的所有规则(即VARCHAR检查字符串长度、NUMERIC检查精度和小数位数等),但还有什么?或者这就足够了吗?对于整数和浮点类型,不需要检查任何内容?)。

我试着浏览Jaybird的源代码,但"转换过程"非常复杂(而且是特定类型的),我自己找不到答案。

JDBC在实际设置值之前不提供任何"检查"值的内容,所以Jaybird也不提供:设置值就是检查。确切的行为取决于驱动程序,Jaybird试图根据设置值进行验证,但其他驱动程序可能会选择将其推迟到数据库本身(因此错误只会在执行时发生)。

通常,您会根据业务需求设计数据库并选择列类型,这自然会在您尝试将其放入数据库之前进行验证。

如果到目前为止还没有做到这一点,那么可以通过限制长度、使用Hibernate Validator或UI框架的验证来开始向输入表单添加验证。

如果您正在处理高度动态的需求(例如用户提供的查询等),那么您应该使用JDBC提供的功能来创建自己的验证:准备好的语句的ParameterMetaData和结果集的ResultSetMetaData(也可以从准备好的声明中访问),特别是这些对象的getPrecision(和getScale),甚至可能是DatabaseMetadata.getColumns之类的东西。

对于字符类型,getPrecision将指示最大字符数,对于numericdecimal类型,您可以将小数点前的最大位数用作precision - scale

然而,在Jaybird中,这并不是100%精确的,例如,如果Jaybird不能识别底层列,getPrecision可能会为numeric(8,2)返回9,而Jaybird(和Firebird)实际上会允许高达精度10的精度,但有一些限制(即,Integer.MAX_VALUE的未缩放最大值,即此类型的21474836.47)。

至于您的第二个问题,使用getter是否会导致转换异常:正常情况下不会,但例如在值大于Integer.MAX_VALUEInteger.MIN_VALUEBIGINT上调用getInt()会。

相关内容

  • 没有找到相关文章

最新更新