java - mybatis 的一些奇怪问题以及 Sybase 的 BigDecimal 上的 isnull

标签 java mybatis bigdecimal isnull

一天前,在添加新的接口(interface)实现后,我在代码中发现了一些奇怪的行为。

我看到 mybatis 更新总是返回 -1,并且表未更新。

Log 告诉我一些有趣的行为:

  • 创建新的 SqlSession
  • SqlSession [...] 未注册同步,因为同步未激活
  • JDBC 连接 [...] 将不会由 Spring 管理
  • ==> 准备:更新卡组 amount=isnull(?, amount), name=isnull(?, name),balanceTime=isnull(?,balanceTime) where number=?和 clientId=?.
  • ==> 参数:0.00(BigDecimal)、测试卡(String)、2017-02-22 09:05:24.78(Timestamp)、0000000000000000(String)、111000(Long)
  • 关闭非事务性 SqlSession [...]

将参数发送到服务器后没有任何反应。 这发生在我的 DAO 被重构之后:

public class DBaseCard{
    private long id;
    private String number;
    private String name;
    private BigDecimal amount; // was Double
    .....
}

在生产中我使用 Sybase IQ。对于测试,我使用 H2 db,一切正常。

如果我将“金额”字段类型更改为 Double,一切正常。

如果我保留 BigDecimal 类型并将“amount=isnull(#{card.amount}, amount)”替换为“amount=#{card.amount}”或类似“amount=isnull(0.00, amount)”的内容,则一切正常,在日志中我看到:

  • ==> 参数:0.0(BigDecimal), ....
  • <==更新:1

请帮助我理解为什么会发生这种情况。

最佳答案

这可能与Sybase中的列类型有关,H2可能有更宽松的行为。

查看 Mybatis default type handlers 的文档:

使用 BigDecimal:

BigDecimalTypeHandler java.math.BigDecimal Any compatible NUMERIC or DECIMAL

双倍:

DoubleTypeHandler java.lang.Double, double Any compatible NUMERIC or DOUBLE

它可能来自isnull函数。您可以尝试用coalesce替换。

尽管在日志中,您会看到 0.00(BigDecimal) , 0.00只是 Java BigDecimal 的字符串表示形式,驱动程序实际绑定(bind)的值可能与 null 相同,例如 0 ,有时0==null0!==null ,这可以解释为什么硬编码 0.00按预期工作。

可以选择编写存储过程。

您也可以考虑使用Mybatis dynamic SQL (trim, where, set) 来构建 SET,这样您就不必再依赖 isnull 了:

UPDATE
<set>
      <if test="amount!= null">amount=#{amount},</if>
      <if test="name!= null">name=#{name},</if>
      <if test="balanceTime!= null">balanceTime=#{balanceTime} </if>
</set>
WHERE number=#{number} AND clientId=#{clientId}

如果您不能保证 SET 中会有某些内容(至少有 1 个非空参数),则<set>必须包含(在最后一行)中性的内容(没有实际更新),例如:id=id .

关于java - mybatis 的一些奇怪问题以及 Sybase 的 BigDecimal 上的 isnull,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42410386/

相关文章:

java - java中的BigDecimal问题

java - 从 BigDecimal 输入中获取小数部分

java - @OneToMany 导致集合不与任何 session 关联

java - 同步方法以防止 ConcurrentModificationException

java - TestNG、Junit、Mockito?

java - MyBatis升级导致构建错误

java - 将 jar 文件放在存储库中的位置

orm - 如何在MyBatis中使用带注释的动态SQL查询(如何使用selectProvider)?

java - 将空列表发送到存储过程

java - Scala 和 Java 中的 RoundingMode.HALF_UP 区别