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