有没有办法在基于注释的 MyBatis/iBatis 中重用 SQL 片段?

Is there a way to reuse SQL fragments in annotation-based MyBatis/iBatis?

MyBatis 在XML-based 定义中有可重用SQL 片段 这个很大的特点,例如:

<mapper namespace="com.company.project.dao.someDao">

    <sql id="whereDate">
        WHERE date(`time`) BETWEEN #{startDate} AND #{endDate}
    </sql>  

    <sql id="someOtherSqlFragment">
        ...
    </sql>

    <select id="getSomeData"
            resultType="SomeClass"
            parameterType="DateParam" >
        SELECT some_column, another_column
    </select>

        FROM some_table

        <include refid="whereDate"/>

        <include refid="otherSqlFragment"/>

    </select>

</mapper>

有没有一种方法可以在基于注释的查询定义中定义和使用此类片段,或者对于这个片段是否没有办法绕过 XMLs?

如果嵌入在 <script> XML 元素中,您可以在注释值中使用 XML 动态 SQL 元素:

@Select("<script>SELECT ...</script>")

但是使用 <include> 元素会触发 SQL Mapper Configuration 解析异常,原因是:

org.apache.ibatis.builder.BuilderException: Unknown element in SQL statement. at org.apache.ibatis.scripting.xmltags.XMLScriptBuilder.parseDynamicTags

如果您检查 class org.apache.ibatis.builder.BuilderException 中的 nodeHandlers 方法,您会注意到支持的元素是:

  • trim
  • 哪里
  • 设置
  • foreach
  • 如果
  • 选择
  • 否则
  • 绑定

那么:不,在基于注释的查询中包含片段是不可能的。