欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Mybatis如何使用ognl表達(dá)式實(shí)現(xiàn)動(dòng)態(tài)sql

 更新時(shí)間:2021年06月10日 10:37:14   作者:張財(cái)華  
這篇文章主要介紹了Mybatis使用ognl表達(dá)式實(shí)現(xiàn)動(dòng)態(tài)sql的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

本文講述在mybatis中如何使用ognl表達(dá)式實(shí)現(xiàn)動(dòng)態(tài)組裝sql語句

新建Users實(shí)體類:

public class Users {
    private Integer uid;
    private String userName;
    private String tel;
    //添加上面私有字段的get、set方法
}

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

public interface UserDao {
    /**
     * 依據(jù)userName查詢用戶信息
     * @param user
     * @return
     */
    List<Users> listUser(Users user);
    /**
     * 動(dòng)態(tài)選擇條件
     * @param user
     * @return
     */
    List<Users> listUser2(Users user);
    /**
     * 動(dòng)態(tài)范圍查詢
     * @param uids
     * @return
     */
    List<Users> listUser3(Integer[] uids);
    /**
     * 動(dòng)態(tài)更新用戶信息
     * @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屬性可以設(shè)置為上面的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根節(jié)點(diǎn)的namespace指定Dao接口的完整類名,
因?yàn)閙ybatis在解析的時(shí)候要根據(jù)這個(gè)類名找到相應(yīng)dao方法執(zhí)行 --><mapper namespace="">   </mapper>

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

<!-- 動(dòng)態(tài)查詢(使用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標(biāo)簽,<where></where>意思就是sql語句中的where,當(dāng)然,where直接在sql中寫出來也可以,<if></if>標(biāo)簽就是條件判斷,test屬性中寫條件語句,如果test中的條件語句為true,那么標(biāo)簽中的sql語句就會(huì)拼接到上面的sql語句中,所以這條sql語句的意思就是如果傳過來的Users對(duì)象中,userName字段不為null,或字段值不為空,那么就添加一個(gè)對(duì)userName的查詢,tel也是如此。

注意:在對(duì)tel字段的判斷時(shí),標(biāo)簽中的sql語句前加了一個(gè)and,如果前一條判斷為false,那么mybatis會(huì)自動(dòng)將and關(guān)鍵字刪除。

<!-- 動(dòng)態(tài)查詢(使用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標(biāo)簽,有點(diǎn)類似于java中的switch-case-default選擇條件語句,相比于if標(biāo)簽,這里只能選擇一個(gè),即多選一。

在這條sql語句中,會(huì)按順序判斷when子句,如果所有的when子句都為false,則會(huì)執(zhí)行otherwise子句中的sql語句。

<!-- 動(dòng)態(tài)查詢(使用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標(biāo)簽適用于范圍查詢(in和or語句),如遍歷一個(gè)id集合,查詢出集合中所有id對(duì)應(yīng)的用戶。在foreach標(biāo)簽中,collection屬性指定需要遍歷的集合的名稱,這里只有一個(gè)參數(shù),所以可以隨意?。籭tem指定遍歷的每一項(xiàng)的別名,open指定在遍歷前需要加上的內(nèi)容,separator指定每遍歷一個(gè)后加上的內(nèi)容,close指定遍歷完后需要加上的內(nèi)容,如遍歷上面的ids集合,那么最終得到的內(nèi)容就是 (1,2,3,4) 。

<!-- 動(dòng)態(tài)更新(使用set動(dòng)態(tài)更新字段) -->
<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標(biāo)簽用于動(dòng)態(tài)設(shè)值,例如在更新數(shù)據(jù)時(shí),可以動(dòng)態(tài)將改變的字段設(shè)置。在trim標(biāo)簽中,prefix屬性表示在更新字段之前添加set關(guān)鍵字,suffixOverrides表示將最后一個(gè)更新字段的逗號(hào)替換成suffix指定的空格符,如果不指定suffix默認(rèn)就是空格。

<!-- 批量添加,利用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標(biāo)簽不僅可以用于范圍查詢,還可以遍歷集合用于批量添加。

因?yàn)榭梢岳胹ql的特性,例如:insert into user_info4(u_name, u_tel) values('', ''), ('', ''), ('', '');這樣執(zhí)行這條sql語句就可以實(shí)現(xiàn)批量添加。

<!-- 批量更新1,這一種方式兼容性較好,當(dāng)數(shù)據(jù)量大時(shí) -->
<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語句,使得一次可以執(zhí)行多條sql,當(dāng)然,如果需要MySql執(zhí)行多條批量操作時(shí),需要開啟批量查詢功能,即在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);

Mybatis中的ognl使用總結(jié)

經(jīng)常在寫mapper中用到一些OGNL,但是沒怎么總結(jié),使用方法一直模模糊糊的。抽點(diǎn)時(shí)間,查了別人的blog,做個(gè)簡(jiǎn)單的總結(jié)

1.概念

OGNL,Object Graph Navigation Language,是一種強(qiáng)大的表達(dá)式語言,網(wǎng)上搜索這個(gè)概念,多是和structs有關(guān)的。但是在mybatis中OGNL應(yīng)用很廣的;

2.基本參數(shù)

Mybatis中常用的OGNL表達(dá)式有以下:

e1 or e2

e1 and e2

e1 == e2,e1 eq e2

e1 != e2,e1 neq e2

e1 lt e2:小于

e1 lte e2:小于等于,其他gt(大于),gte(大于等于)

e1 in e2

e1 not in e2

e1 + e2,e1 * e2,e1/e2,e1 - e2,e1%e2

!e,not e:非,求反

e.method(args)調(diào)用對(duì)象方法

e.property對(duì)象屬性值

e1[ e2 ]按索引取值,List,數(shù)組和Map

@class@method(args)調(diào)用類的靜態(tài)方法

@class@field調(diào)用類的靜態(tài)字段值

更加詳細(xì)的介紹可以參考官網(wǎng)的介紹:https://commons.apache.org/proper/commons-ognl/language-guide.html

在一定意義上說,mybatis中的動(dòng)態(tài)sql也是基于OGNL表達(dá)式的。其中常用的元素有如下幾種:

    if
    choose(when,otherwise)
    trim
    where
    set
    foreach

3.應(yīng)用;

OGNL在mybatis中的應(yīng)用,主要有兩種;

1)動(dòng)態(tài)SQL表達(dá)式;

舉個(gè)栗子:

<code class="language-xml hljs  has-numbering"><span class="hljs-tag"><<span class="hljs-title">select</span> <span class="hljs-attribute">id</span>=<span class="hljs-value">"demo1"</span> <span class="hljs-attribute">...</span>></span>
</code><pre name="code" class="prettyprint"><code class="language-xml hljs  has-numbering">    select id, name from users
    <span class="hljs-tag"><<span class="hljs-title">bind</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"nameLike"</span> <span class="hljs-attribute">value</span>=<span class="hljs-value">"'%' + name + '%'"</span>/></span>
    <span class="hljs-tag"><<span class="hljs-title">where</span>></span>
        <span class="hljs-tag"><<span class="hljs-title">if</span> <span class="hljs-attribute">test</span>=<span class="hljs-value">"name != null and name != ''"</span>></span>
            name like '${nameLike}'
        <span class="hljs-tag"></<span class="hljs-title">if</span>></span>
    <span class="hljs-tag"></<span class="hljs-title">where</span>></span>
<span class="hljs-tag"></<span class="hljs-title">select</span>></span></code>

其中的bind中的value值會(huì)使用OGNL計(jì)算,ps,其中bind的參數(shù)調(diào)用只能用$獲?。?/p>

2)${param}參數(shù)中

<code class="language-xml hljs  has-numbering"><span class="hljs-tag"><<span class="hljs-title">select</span> <span class="hljs-attribute">id</span>=<span class="hljs-value">"demo2"</span> <span class="hljs-attribute">...</span>></span>
    select id,name from users
    <span class="hljs-tag"><<span class="hljs-title">where</span>></span>
        <span class="hljs-tag"><<span class="hljs-title">if</span> <span class="hljs-attribute">test</span>=<span class="hljs-value">"name != null and name != ''"</span>></span>
            name like '${'%' + name + '%'}'
        <span class="hljs-tag"></<span class="hljs-title">if</span>></span>
    <span class="hljs-tag"></<span class="hljs-title">where</span>></span>
<span class="hljs-tag"></<span class="hljs-title">select</span>></span></code>

此處寫的是 ${'%' + name + '%'},而不是 %${name}%,這兩種方式的結(jié)果一樣,但是處理過程不一樣。

ps,說明一下#和$的區(qū)別:${} 為原樣輸出,你傳什么,sql里就填入什么,比如有引號(hào)它也會(huì)原樣填到sql里。#{} 會(huì)使用 PreparedStatement,變量處用 ? 代替。

在能使用 #{} 盡量使用它吧,可以防止sql注入。

以下是一個(gè)OGNL的調(diào)用靜態(tài)方法的示例:

    <select id="getRecentQuestionTitle" parameterType="java.lang.String" resultType="java.lang.String">  
            select title from song_question where questionState = #{value}   
            <if test="@Ognl@isSolve(value[0],0)">  
            order by questionTime desc   
            </if>  
            <if test="@Ognl@isSolve(value[0],1)">  
            order by answerTime desc   
            </if>                
            limit 0,1  
      </select>  

靜態(tài)方法如下:

public static boolean isSolve(Object o,String soleState){  
        if(o == null)  
            return false;  
        String str = null;  
        if(o instanceof String[]){  
            String[]objects = (String[])o;  
            str = objects[0];  
        }else if(o instanceof Character){  
            Character c = (Character) o;  
            str =  Character.toString(c);  
        }  
            if(StringUtils.equals(str, soleState))  
                return true;  
        return false;  
          
    } 

如果值為0,則order by questionTime desc 根據(jù)字段questionTime排序。

如果值為1,則order by answerTime desc根據(jù)字段answerTime排序。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • java常用工具類之DES和Base64加密解密類

    java常用工具類之DES和Base64加密解密類

    這篇文章主要介紹了java常用工具類之DES和Base64加密解密類,需要的朋友可以參考下
    2014-07-07
  • SpringBoot或SpringAI對(duì)接DeepSeek大模型的詳細(xì)步驟

    SpringBoot或SpringAI對(duì)接DeepSeek大模型的詳細(xì)步驟

    這篇文章主要介紹了DeepSeek智能助手的使用方法和步驟,包括引入庫、配置環(huán)境變量和配置,文章詳細(xì)描述了流式請(qǐng)求和非流式請(qǐng)求的實(shí)現(xiàn)方式,需要的朋友可以參考下
    2025-02-02
  • 詳解SpringBoot的事務(wù)管理

    詳解SpringBoot的事務(wù)管理

    Springboot內(nèi)部提供的事務(wù)管理器是根據(jù)autoconfigure來進(jìn)行決定的。接下來通過本文給大家介紹SpringBoot的事務(wù)管理相關(guān)知識(shí),感興趣的朋友一起學(xué)習(xí)吧
    2017-04-04
  • SpringBoot設(shè)置Session失效時(shí)間的解決方案

    SpringBoot設(shè)置Session失效時(shí)間的解決方案

    當(dāng)過期時(shí)間是大于1分鐘的時(shí)候是沒有什么問題的,但是如果設(shè)置過期時(shí)間小于1分鐘,就會(huì)失效,這篇文章主要介紹了SpringBoot設(shè)置Session失效時(shí)間的解決方案,需要的朋友可以參考下
    2024-05-05
  • Java?Record的實(shí)現(xiàn)示例

    Java?Record的實(shí)現(xiàn)示例

    本文主要介紹了Java?Record的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-04-04
  • Spring為singleton?bean注入prototype?bean

    Spring為singleton?bean注入prototype?bean

    這篇文章主要介紹了Spring為singleton?bean注入prototype?bean,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-07-07
  • Spring Boot Maven Plugin打包異常解決方案

    Spring Boot Maven Plugin打包異常解決方案

    這篇文章主要介紹了Spring Boot Maven Plugin打包異常解決方案,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11
  • Java執(zhí)行JS腳本工具

    Java執(zhí)行JS腳本工具

    今天小編就為大家分享一篇關(guān)于Java執(zhí)行JS腳本工具,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • Spring Security之LogoutSuccessHandler注銷成功操作方式

    Spring Security之LogoutSuccessHandler注銷成功操作方式

    這篇文章主要介紹了Spring Security之LogoutSuccessHandler注銷成功操作方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • 如何優(yōu)雅的實(shí)現(xiàn)將Collection轉(zhuǎn)為Map

    如何優(yōu)雅的實(shí)現(xiàn)將Collection轉(zhuǎn)為Map

    這篇文章主要介紹了如何優(yōu)雅的實(shí)現(xiàn)將Collection轉(zhuǎn)為Map,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-03-03

最新評(píng)論