重用动态sql片段

The*_*heo 3 mybatis

嘿那里,我正在研究一个Primefaces应用程序,作为一个持久层,我选择了Mybatis.

这是常规sql在我的mapper中的样子:

<select id="getAllTransportUnit" resultMap="TransportUnitMap">
    SELECT * FROM SSLS_GUI.VW_TU
    <if test="( hasFilters == 'yes' ) and ( parameters != null )">
        <where>
            <foreach item="clause" collection="parameters" separator=" AND "
                open="(" close=")">
                UPPER(${clause.column}) ${clause.operator} #{clause.value}
            </foreach>
        </where>
    </if>
    <if test="sort == 'true'">
        ORDER BY ${sortField}
        <if test="sortOrder == 'DESC'"> DESC</if>
        <if test="sortOder == 'ASC'"> ASC</if>
    </if>
</select>
Run Code Online (Sandbox Code Playgroud)

几乎所有的查询都使用动态sql部分<if test...>.是否可以将它放在一个单独的文件中,然后在我的查询中重复使用它?

Rom*_*val 10

有几种选择如何重用sql片段.

SQL片段和包含

第一个是使用include.创建单独的映射器Common.xml:

<mapper namespace="com.company.project.common">
    <sql id="orderBy>
      <if test="sort == 'true'">
        ORDER BY ${sortField}
        <if test="sortOrder == 'DESC'"> DESC</if>
        <if test="sortOder == 'ASC'"> ASC</if>
      </if>
    </sql>


    <sql id="filters">
     <if test="( hasFilters == 'yes' ) and ( parameters != null )">
      <where>
        <foreach item="clause" collection="parameters" separator=" AND "
            open="(" close=")">
            UPPER(${clause.column}) ${clause.operator} #{clause.value}
        </foreach>
     </where>
    </if>
  </sql>
</mapper>
Run Code Online (Sandbox Code Playgroud)

并在其他映射器中使用它MyMapper.xml:

<select id="getAllTransportUnit" resultMap="TransportUnitMap">
  SELECT * FROM SSLS_GUI.VW_TU
  <include refid="com.company.project.common.filters"/>
  <include refid="com.company.project.common.orderBy"/>
</select>
Run Code Online (Sandbox Code Playgroud)

为避免在每个包含中复制命名空间,您可以在MyMapper.xml以下位置创建快捷方式摘要:

<sql id="orderBy">
  <include refid="com.company.project.common.orderBy"/> 
</sql>

<select id="getAllTransportUnit" resultMap="TransportUnitMap">
  SELECT * FROM SSLS_GUI.VW_TU
  <include refid="orderBy"/>
</select>
Run Code Online (Sandbox Code Playgroud)

Mybatis速度宏

另一种可能的选择是使用mybatis 脚本.使用mybatis-velocity脚本引擎,您可以定义速度宏并重新使用它.

Commons.xml:

<sql id="macros"
  #macro(filters)
    #if ( $_parameter.hasFilters )
      #repeat( $_parameter.parameters $clause "AND" " (" ")" )
        ${clause.column} ${clause.operator} @{clause.value}
      #end
    #end
  #end

  #macro(order_by)
  .. 
  #end
</sql>
Run Code Online (Sandbox Code Playgroud)

MyMapper.xml:

<select id="getAllTransportUnit" resultMap="TransportUnitMap">
  <include refid="macros"/>
  SELECT * FROM SSLS_GUI.VW_TU
  #filters()
  #order_by()
</select>
Run Code Online (Sandbox Code Playgroud)

通过sql代码片段包含宏并不是重用宏的最简洁方法.这只是一个想法如何使用它.

更好的选择是配置mybatis-velocity并指定可用的全局宏.在这种情况下,不需要包含macros片段,结果查询将如下所示:

<select id="getAllTransportUnit" resultMap="TransportUnitMap">
  SELECT * FROM SSLS_GUI.VW_TU
  #filters()
  #order_by()
</select>
Run Code Online (Sandbox Code Playgroud)