MyBatis-DynamicSQL 動態SQL


MyBatis 的動態 SQL 使用 OGNL 表達式

http://commons.apache.org/proper/commons-ognl/language-guide.html

在 XML 中的一些特殊字符需要轉義,參考 HTML ISO-8859-1 手冊

http://www.w3school.com.cn/tags/html_ref_entities.html

 

一、IF

https://www.cnblogs.com/jhxxb/p/10637219.html

<select id="selectMyUserByIF" resultType="myUser" parameterType="myUser">
    select * from myuser where
    <if test="id != null">
      id = #{id}
    </if>
    <if test="name != null &amp;&amp; name != &quot;&quot;">
      and name like #{name}
    </if>
    <if test="age == 0 or age == 1">
      and age = #{age}
    </if>
</select>

入參沒有ID屬性時會報錯,會拼接成 where and,解決:可以在 where 后添加一個恆成立,如 1=1。或者使用 where 標簽,會自動去除 SQL 中多出來的 and 或 or

 

二、WHERE

<select id="selectMyUserByIF" resultType="myUser" parameterType="myUser">
    select * from myuser
    <where>
        <if test="id != null">
          id = #{id}
        </if>
        <if test="name != null and name != ''.toString()">
          and name like #{name}
        </if>
        <if test="age == 0 or age == 1">
          and age = #{age}
        </if>
    </where>
</select>

where 標簽只能去除第一個 and 或 or,所以不能把條件符號寫多個或寫在后面

 

三、SET

<update id="updateMyUser" parameterType="myUser">
    update myuser
    <!-- 用作更新 -->
    <set>
        <if test="name != null">
          name = #{name},
        </if>
        <if test="age != null">
          age = #{age}
        </if>
    </set>
    where id = #{id}
</update>

 

四、TRIM

<select id="selectMyUserByIF" resultType="myUser" parameterType="myUser">
    select * from myuser
    <!-- prefix:替換拼接后字符串的前綴,單獨使用則為添加。prefixOverrides:想替換的前綴類容(條件),單獨使用則為刪除
        suffix:替換拼接后字符串的后綴,單獨使用則為添加。suffixOverrides:想替換的后綴類容(條件),單獨使用則為刪除 -->
    <trim prefix="where" prefixOverrides="AND | OR" suffixOverrides="and">
        <if test="id != null">
            id = #{id} and
        </if>
        <if test="name != null and name.trim() != ''">
            name like #{name}
        </if>
    </trim>
</select>

trim 標簽可以替代 where 標簽

<!-- 等效於 where 標簽 -->
<trim prefix="WHERE" prefixOverrides="AND |OR ">
    ...
</trim>

trim 標簽也可以替代 set 標簽

<!-- 等效於 set 標簽 -->
<trim prefix="set" suffixOverrides=",">
  ...
</trim>

 

五、CHOOSE

<select id="selectMyUserByIF" resultType="myUser" parameterType="myUser">
    select * from myuser
    <where>
        <!-- 類似於 if-else if-else 分支結構 -->
        <choose>
            <when test="id != null">
              id = #{id}
            </when>
            <when test="name != null and name.trim() != ''">
              name like #{name}
            </when>
            <otherwise>
              age = 22
            </otherwise>
        </choose>
    </where>
</select>

 

六、FOREACH

Map 入參

<!--public List<MyUser> selectMyUserByArray(Map<String,Object> maps);-->
<select id="selectMyUserByArray" resultType="myUser">
    select * from myuser where id in
    <!-- collection:指定要遍歷的集合或數組(list 和 array 參數都會特殊處理封裝在 Map 中,Map 的 key 默認為 list 或 array)
            入參為單個 list 或 array 時 collection 值默認為 list 或 array,若接口方法指定了 @Param 注解,則為 @Param 的值
            入參為多個參數可以封裝為 Map,collection 值為 Map 中集合或數組對應的 key 的值(Map 的 key 最好為 String 類型)
        open:給結果拼接一個前綴
        close:給結果拼接一個后綴
        item:集合中每一個元素在迭代時的別名,#{item} 取出變量的值,也就是當前遍歷出的元素
        separator:每個元素之間的分隔符
        index:索引
            遍歷 list 或 arrays 時,index 是當前索引(下標),item 為索引對應的值
            遍歷 map 時 index 表示 map 的 key,item 為 map 的 value -->
    <foreach collection="ids" item="item" index="index" separator="," open="(" close=")">
        #{item}
    </foreach>
</select>

測試代碼

public static void main(String[] args) {
    SqlSession session = null;
    try {
        InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        session = sqlSessionFactory.openSession();

        MyUserMapper mapper = session.getMapper(MyUserMapper.class);
        Map<String,Object> ids = new HashMap<>(10);
        ids.put("ids",Arrays.asList(7,8,9,10));
        ids.put("b",8);
        System.out.println(mapper.selectMyUserByArray(ids));
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (session != null) {
            session.close();
        }
    }
}

List 入參

<!--public List<MyUser> selectMyUserByArray(List<Integer> ids);-->
<select id="selectMyUserByArray" resultType="myUser">
    select * from myuser where id in
    <foreach collection="list" item="item" index="index" separator="," open="(" close=")">
      #{item}
    </foreach>
</select>

Array 入參

<!--public List<MyUser> selectMyUserByArray(Integer[] ids);-->
<select id="selectMyUserByArray" resultType="myUser">
    select * from myuser
    <foreach collection="array" item="item" index="index" separator="," open="where id in (" close=",20)">
      #{item}
    </foreach>
</select>

 

 

七、內置參數

<!-- 不只是方法傳遞過來的參數可以被用來判斷和取值,mybatis 默認還有兩個內置參數。
        _parameter:代表整個參數
            單個參數:_parameter 就是這個參數
            多個參數:參數會被封裝為一個 map,_parameter 就代表這個 map
        _databaseId:如果配置了 databaseIdProvider 標簽,_databaseId 代表當前數據庫的別名 -->
<select id="selectMyUserById" resultType="myUser">
    <if test="_databaseId == 'mysql'">
        select * from myuser
        <if test="_parameter != null">
            where id = #{_parameter}
        </if>
    </if>
    <if test="_databaseId == 'oracle'">
        select * from oracle_myuser
        <if test="_parameter != null">
            where name = #{_parameter.name}
        </if>
    </if>
</select>

 

八、BIND

<select id="selectMyUserByNameLike" resultType="myUser" parameterType="string">
    select * from myuser where name like #{name}
</select>

例 SQL 映射想變為模糊查詢有幾種方式

1.傳入參數時加上 %

2.改用 ${name} 來取值。name 取值會報錯,用 _parameter 取值

<select id="selectMyUserByNameLike" resultType="myUser">
    select * from myuser where name like '%${_parameter}%'
</select>

3.使用 bind 標簽

<select id="selectMyUserByNameLike" resultType="myUser">
  <!-- bind:可以將OGNL表達式的值綁定到一個變量中,方便后來引用這個變量的值 -->
    <bind name="_name" value="'%'+_parameter+'%'"/>
    select * from myuser where name like #{_name}
</select>

 

九、SQL 復用

<!-- 抽取可重用的sql片段。方便后面引用,使用 include 標簽來引用已經抽取的 sql
    include 中可以自定義一些 property,sql 標簽內部就能使用自定義的屬性
    include-property:取值用 ${prop}, 使用 #{prop} 不能取出,無法預編譯 -->
<sql id="columnNames">
    <if test="_databaseId=='mysql'">
        ${id},name,age
    </if>
    <if test="_databaseId=='oracle'">
        xxx,xxx,xxx
    </if>
</sql>
<select id="selectMyUserByNameLike" resultType="myUser" parameterType="string">
    select
    <include refid="columnNames">
      <property name="id" value="id"/>
    </include>
    from myuser where name like #{name}
</select>

 


可以使用其他語言來寫動態 SQL:MyBatis-Velocity、MyBatis-FreeMarker 和自帶的 XML

http://www.mybatis.org/velocity-scripting/

http://www.mybatis.org/freemarker-scripting/

https://www.jianshu.com/p/cecc187410be

MyBatis 動態 SQL 文檔


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM