Mybatis——使用ognl表達式實現動態sql


本文講述在mybatis中如何使用ognl表達式實現動態組裝sql語句

新建Users實體類:

public class Users {
    private Integer uid;
    private String userName;
    private String tel;

    //添加上面私有字段的get、set方法
}

新建一個Dao接口類,mybatis配置文件在配置namespace屬性時需要加入這個類的完整類名,找到這個類里的方法執行:

public interface UserDao {

    /**
     * 依據userName查詢用戶信息
     * @param user
     * @return
     */
    List<Users> listUser(Users user);

    /**
     * 動態選擇條件
     * @param user
     * @return
     */
    List<Users> listUser2(Users user);

    /**
     * 動態范圍查詢
     * @param uids
     * @return
     */
    List<Users> listUser3(Integer[] uids);

    /**
     * 動態更新用戶信息
     * @param user
     */
    void updateUser(Users user);

    /**
     * 批量添加
     * @param list
     */
    void addBatch(List<Users> list);

    /**
     * 批量刪除
     * @param ids
     */
    void deleteBatch(int[] ids);

    /**
     * 批量更新
     * @param list
     */
    void updateBatch1(List<Users> list);

    /**
     * 批量更新
     * @param list
     */
    void updateBatch2(List<Users> list);
}

新建mybatis的配置文件(下面代碼可以作為mybatis配置文件的模板,這里的namespace屬性可以設置為上面的dao類的完整類名):

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- mapper根節點的namespace指定Dao接口的完整類名,
因為mybatis在解析的時候要根據這個類名找到相應dao方法執行 -->
<mapper namespace="">
    
</mapper>

在mybatis配置文件中寫一條條件查詢sql語句:

 

<!-- 動態查詢(使用if拼接條件,適用於多選多的形式) -->
<select id="listUser" parameterType="users" resultMap="userMap">
    select u_id, u_name, u_tel from user_info4 user_info
    <where>
        <if test="userName != null and userName !=''">
            u_name = #{userName}
        </if>
        <if test="tel != null and tel !=''">
            and u_tel = #{tel}
        </if>
    </where>
</select>

這里使用了where和if標簽,<where></where>意思就是sql語句中的where,當然,where直接在sql中寫出來也可以,<if></if>標簽就是條件判斷,test屬性中寫條件語句,如果test中的條件語句為true,那么標簽中的sql語句就會拼接到上面的sql語句中,所以這條sql語句的意思就是如果傳過來的Users對象中,userName字段不為null,或字段值不為空,那么就添加一個對userName的查詢,tel也是如此。注意:在對tel字段的判斷時,標簽中的sql語句前加了一個and,如果前一條判斷為false,那么mybatis會自動將and關鍵字刪除。

 

<!-- 動態查詢(使用choose選擇條件,適用於多選一) -->
<select id="listUser2" parameterType="users" resultMap="userMap">
    select u_id, u_name, u_tel from user_info4
    <choose>
        <when test="userName != null and userName != ''">
            where u_name = #{userName}
        </when>
        <when test="tel != null and tel != ''">
            where u_tel = #{tel}
        </when>
        <otherwise>
            order by u_id desc
        </otherwise>
    </choose>
</select>

這里使用的是choose-when-otherwise標簽,有點類似於java中的switch-case-default選擇條件語句,相比於if標簽,這里只能選擇一個,即多選一。在這條sql語句中,會按順序判斷when子句,如果所有的when子句都為false,則會執行otherwise子句中的sql語句。

 

<!-- 動態查詢(使用foreach范圍查詢,適用於in和or語句) -->
<!-- int[] ids = new int[]{1,2,3,4}; -->
<select id="listUser3" parameterType="collection" resultMap="userMap">
    select u_id, u_name, u_tel from user_info4
    <where>
        u_id in
        <if test="array != null">
            <foreach collection="array" item="id" open="(" separator="," close=")">
                #{id}
            </foreach>
        </if>
    </where>
</select>

foreach標簽適用於范圍查詢(in和or語句),如遍歷一個id集合,查詢出集合中所有id對應的用戶。在foreach標簽中,collection屬性指定需要遍歷的集合的名稱,這里只有一個參數,所以可以隨意取;item指定遍歷的每一項的別名,open指定在遍歷前需要加上的內容,separator指定每遍歷一個后加上的內容,close指定遍歷完后需要加上的內容,如遍歷上面的ids集合,那么最終得到的內容就是 (1,2,3,4) 。

 

<!-- 動態更新(使用set動態更新字段) -->
<update id="updateUser" parameterType="users" >
    update user_info4
    <trim prefix="set" suffixOverrides=",">
        <if test="userName != null and userName != ''">
            u_name = #{userName},
        </if>
        <if test="tel != null and tel != ''">
            u_tel = #{tel}
        </if>
    </trim>
    <!-- where u_id = #{uid} -->
    <where>
        u_id = #{uid}
    </where>
</update>

trim標簽用於動態設值,例如在更新數據時,可以動態將改變的字段設置。在trim標簽中,prefix屬性表示在更新字段之前添加set關鍵字,suffixOverrides表示將最后一個更新字段的逗號替換成suffix指定的空格符,如果不指定suffix默認就是空格。

 

<!-- 批量添加,利用sql的特性 -->
<insert id="addBatch" parameterType="list">
    insert into user_info4(u_id, u_name, u_tel) values
    <foreach collection="list" item="user" separator=",">
        (#{user.uid}, #{user.userName}, #{user.tel})
    </foreach>
</insert>

foreach標簽不僅可以用於范圍查詢,還可以遍歷集合用於批量添加。因為可以利用sql的特性,例如:insert into user_info4(u_name, u_tel) values('', ''), ('', ''), ('', '');這樣執行這條sql語句就可以實現批量添加。

 

<!-- 批量更新1,這一種方式兼容性較好,當數據量大時 -->
<update id="updateBatch1" parameterType="list">
    <foreach collection="list" item="user" separator=";">
        update user_info4
        <set>
            u_name = #{user.userName}
        </set>
        where u_id = #{user.uid}
    </foreach>
</update>

foreach還可以用於遍歷出多條sql語句,使得一次可以執行多條sql,當然,如果需要MySql執行多條批量操作時,需要開啟批量查詢功能,即在MySql的url中加入 allowMultiQueries=true 。

 

<!-- 批量更新2,使用MySQL的case when語句 -->
    <update id="updateBatch2" parameterType="list">
        update user_info4 set u_name = case u_id
        <foreach collection="list" item="user" separator=" ">
            when #{user.uid} then #{user.userName}
        </foreach>
        end
        where u_id in
        <foreach collection="list" item="user" open="(" close=")" separator=",">
            #{user.uid}
        </foreach>
    </update>

這里使用的是MySql中的case when語句來更新的,基本語法:

update user_info4 set u_name = case u_id

  when 3 then '游客1'

  when 4 then '游客2'

  end

  where u_id in(3,4);

 


免責聲明!

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



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