MyBatis dynamic “union all”

Take a look at the following union sql fragment. What if includeFoo is false?

    <sql id="dynamic_union">
      

            <if test="includeFoo">
                (select * from foo)
            
            </if>

            <if test="includeBar">
                union all
                (select * from bar)
            </if>
 

    </sql>

You will end up with

union all (select * from bar)

, which is not legal sql. There must be a result set before “union all”

The solution is to use <trim/> tag

    <sql id="dynamic_union">
        <trim  prefixOverrides="union all">


            <if test="includeFoo">
                (select * from foo)
            
            </if>

            <if test="includeBar">
                union all
                (select * from bar)
            </if>
 

        </trim>


    </sql>

It means: if what’s inside <trim/> starts with “union all”, then “union all” will be removed