ibatis to mybatis.Part 2

在转换的过程中,陆续遇到了几个问题

jdbcType大小写问题

Build.xml
<replace dir="destination" includes="*.xml" token=":NUMERIC#" value=",jdbcType=NUMERIC#" encoding="UTF8"/>
<replace dir="destination" includes="*.xml" token=":TIMESTAMP#" value=",jdbcType=TIMESTAMP#" encoding="UTF8"/>
<replace dir="destination" includes="*.xml" token=":VARCHAR#" value=",jdbcType=VARCHAR#" encoding="UTF8"/>

jdbcType的大小写需要实现转换,另外需要添加更多的类型。

dynamic的转换缺失

默认的migrate.xslt没有对dynamic element做转换,需要新增转换逻辑。

首先确定dynamic element的定义,ibatis.dtd中可以找到

<!--Wrapper tag that allows for an overall prepend, open and close.-->
<!ELEMENT dynamic (#PCDATA | include | iterate | isParameterPresent | isNotParameterPresent | isEmpty | isNotEmpty | isNotNull | isNull | isNotEqual | isEqual | isGreaterThan | isGreaterEqual | isLessThan | isLessEqual | isPropertyAvailable | isNotPropertyAvailable)*>
<!ATTLIST dynamic
prepend CDATA #IMPLIED
open CDATA #IMPLIED
close CDATA #IMPLIED
>

然后将dynamic element的处理逻辑加入到migrate.xslt中。

migrate.xslt
<xsl:template match="dynamic">
    <xsl:element name="trim">
        <xsl:attribute name="prefix">
            <xsl:value-of select="@prepend" />
        </xsl:attribute>
        <xsl:attribute name="prefixOverrides">
            <xsl:text>and|or|,</xsl:text>
        </xsl:attribute>
        <xsl:value-of select="@open" />
        <xsl:apply-templates/>
        <xsl:value-of select="@close" />
    </xsl:element>  
</xsl:template>

效果如下:

ibatis source
<dynamic prepend=" where " close="and (1=1)">
  <isNotNull property="offerId" prepend="and">
    item_id=#offerId#
  </isNotNull>
</dynamic>

mybatis target
<trim prefix=" where " prefixOverrides="and|or|,">
  <if test="offerId != null">and
    item_id=#{offerId}
  </if>
</trim>


isNotEmpty的翻译错误

原先isNotEmpty的转换逻辑为:

<xsl:template match="isNotEmpty">
  <xsl:element name="if">
    <xsl:attribute name="test">
      <xsl:if test="substring-before(@property, '.')">
        <xsl:value-of select="substring-before(@property, '.')" /><xsl:text> != null and </xsl:text>
      </xsl:if>
      <xsl:value-of select="@property" /><xsl:text> != null and </xsl:text>
      <xsl:value-of select="@property" /><xsl:text>.size != 0</xsl:text>
    </xsl:attribute>
    <xsl:value-of select="@prepend" />
      <xsl:apply-templates/>
    </xsl:element>
</xsl:template>

但是当遇到iterate类型时,直接!=”是会报错的。需要针对iterate类型,修改isNotEmpty的逻辑

<xsl:template match="isNotEmpty">
  <xsl:element name="if">
    <xsl:attribute name="test">
      <xsl:if test="substring-before(@property, '.')">
        <xsl:value-of select="substring-before(@property, '.')" /><xsl:text> != null and </xsl:text>
      </xsl:if>
      <xsl:value-of select="@property" /><xsl:text> != null and </xsl:text>
      <xsl:choose>
        <xsl:when test="child::node()[contains(name(), 'iterate')]">
          <xsl:value-of select="@property" /><xsl:text>.size != 0</xsl:text>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="@property" /><xsl:text> != ''</xsl:text>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:attribute>
    <xsl:value-of select="@prepend" />
      <xsl:apply-templates/>
    </xsl:element>
</xsl:template>

最终的转换效果如下:

ibatis source
<isNotEmpty property="offerIds" prepend="and">
  item_id in
  <iterate property="offerIds" conjunction="," open="(" close=")">
    #offerIds[]#
  </iterate>
</isNotEmpty>

mybatis target
<if test="offerIds != null and offerIds.size != 0">and
  item_id in
  <foreach collection="offerIds" item="item" separator="," close=")" open="(">
    #{item}
  </foreach>
</if>

发表评论