Search code examples
javaannotationsmybatisibatis

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


MyBatis has this great feature of reusable SQL fragments in XML-based definition, such as:

<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>

Is there a way to define and use such fragments in the annotation-based definition of the queries or is there no way around XMLs for this one?


Solution

  • You can use XML elements for dynamic SQL in the annotation value if it is embedded in <script> XML element:

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

    But using <include> element will trigger a SQL Mapper Configuration parse exception, caused by:

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

    If you check the nodeHandlers method in class org.apache.ibatis.builder.BuilderException, you will note the supported elements are:

    • trim
    • where
    • set
    • foreach
    • if
    • choose
    • when
    • otherwise
    • bind

    Then: NO, including fragment in annotation-based queries is not possible.