在转换的过程中,陆续遇到了几个问题
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>