首頁 > 資料庫 > SQL > 主體

學習MyBatis 動態 SQL

coldplay.xixi
發布: 2020-12-09 17:46:13
轉載
2750 人瀏覽過

sql教學介紹SQL MyBatis的強大特性SQL

學習MyBatis 動態 SQL

#推薦(免費):sql教學

#動態SQL

MyBatis 的強大功能之一就是它的動態SQL。如果你有使用 JDBC 或其它類似框架的經驗,你就能體會到根據不同條件拼接 SQL 語句的痛苦。例如拼接時要確保不能忘記加入必要的空格,也要注意去掉列表最後一個列名的逗號。利用動態 SQL 這項特性可以徹底擺脫這種痛苦。

雖然在先前使用動態 SQL 並非一件易事,但正是 MyBatis 提供了可以被用在任意 SQL 映射語句中的強大的動態 SQL 語言得以改進這種情況。

動態 SQL 元素和 JSTL 或基於類似 XML 的文字處理器相似。在 MyBatis 之前的版本中,有許多元素需要花時間了解。 MyBatis 3 大大精簡了元素種類,現在只需學習原來一半的元素便可。 MyBatis 採用功能強大的基於 OGNL 的表達式來淘汰其它大部分元素。

準備

先建立User實體類別

public class User {
    private Integer id;
    private String username;
    private String userEmail;
    private String userCity;
    private Integer age;}
登入後複製

建立user表
CREATE TABLE user (
  id int(11) NOT NULL AUTO_INCREMENT,
  username varchar(255) DEFAULT NULL,
    user_email varchar(255) DEFAULT NULL,
    user_city varchar(255) DEFAULT NULL,
    age int(11) DEFAULT NULL,
  PRIMARY KEY (id))
登入後複製

if

定義介面方法

public List<User> findByUser(User user);
登入後複製

介面對應的Mapper.xml 定義如下所示

<select id="findByUser" resultType="com.example.mybatis.entity.User">
    select
    id, username, user_email userEmail, user_city userCity, age
    from user
    where    <if test="username != null and username != &#39;&#39;">
        username = #{username}    </if>
    <if test="userEmail != null and userEmail != &#39;&#39;">
        and user_email = #{userEmail}    </if>
    <if test="userCity != null and userCity != &#39;&#39;">
        and user_city = #{userCity}    </if></select>
登入後複製

如果if標籤上的test為true,那麼if標籤裡面的SQL語句將會被拼接。

如果username、userEmail、userCity都不為空,那麼SQL將會拼接成如下所示

select id, username, user_email userEmail, user_city userCity, age 
from user where username = ? and user_email = ? and user_city = ?
登入後複製

如果只有username不為空,那麼SQL將會拼接成如下所示

select id, username, user_email userEmail, user_city userCity, age 
from user where username = ?
登入後複製

但這種方式有一個缺點,假設此時username為空,userEmail、userCity都不為空。

我們來分析動態SQL 程式碼,現在沒有給username 賦值,也就是username==null,所以「username=#{username}」 這段程式碼不會加入到SQL 語句中,那麼最終拼接好的動態SQL 是這樣的:<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">select id, username, user_email userEmail, user_city userCity, age  from user where and user_email = ? and user_city = ?</pre><div class="contentsignin">登入後複製</div></div>where 後面直接跟and,很明顯的語法錯誤,此時應該把緊跟在where後面的and刪掉。為了解決這個問題,可以使用

where

標籤。

where

將上面的SQL改成如下圖<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">    &lt;select id=&quot;findByUser&quot; resultType=&quot;com.example.mybatis.entity.User&quot;&gt;         select         id, username, user_email userEmail, user_city userCity, age        from user         &lt;where&gt;             &lt;if test=&quot;username != null and username != &amp;#39;&amp;#39;&quot;&gt;                 username = #{username}             &lt;/if&gt;             &lt;if test=&quot;userEmail != null and userEmail != &amp;#39;&amp;#39;&quot;&gt;                 and user_email = #{userEmail}             &lt;/if&gt;             &lt;if test=&quot;userCity != null and userCity != &amp;#39;&amp;#39;&quot;&gt;                 and user_city = #{userCity}             &lt;/if&gt;         &lt;/where&gt;     &lt;/select&gt;</pre><div class="contentsignin">登入後複製</div></div>如果where標籤裡面的if 標籤有滿足條件的,那麼where標籤就會被拼接成where語句,若

if

標籤拼接的SQL最前面有and語句,那麼這個and將會被刪除。使用這種方法, 會自動刪除SQL中不需要的關鍵字,所以一般 if 標籤和 where 標籤會組合起來使用。

trimtrim標籤中的prefix

suffix

屬性會被用來生成實際的SQL 語句,會跟標籤內部的語句拼接。 如果語句的前面或後面遇到 prefixOverrides

suffixOverrides

屬性中指定的值,MyBatis 會自動刪除它們。在指定多個值的時候,別忘了每個值後面都要有一個空格,保證不會和後面的 SQL 連接在一起。

prefix

:在拼接的SQL語句中加上一個前綴

suffix

:在拼接的SQL語句中加上一個字尾

##prefixOverrides:拼接的SQL語句前面遇到

prefixOverrides

,MyBatis 會自動將它們刪除suffixOverrides:拼接的SQL語句後面遇到

suffixOverrides

,MyBatis 會自動刪除它們下面使用

trim

標籤來實作where標籤的功能

<select id="findByUser" resultType="com.example.mybatis.entity.User">
        select
        id, username, user_email userEmail, user_city userCity, age
        from user        <trim prefix="where" prefixOverrides="and">
            <if test="username != null and username != &#39;&#39;">
                username = #{username}            </if>
            <if test="userEmail != null and userEmail != &#39;&#39;">
                and user_email = #{userEmail}            </if>
            <if test="userCity != null and userCity != &#39;&#39;">
                and user_city = #{userCity}            </if>
        </trim>
    </select>
登入後複製

如果username為空,userEmail和userCity不為空,那麼

if

標籤拼接的SQL語句如下所示
and user_email = #{userEmail} and user_city = #{userCity}
登入後複製
因為

trim

標籤設定了prefixOverrides=”and” ,而上面的SQL前面有and語句,所以需要將上面的and語句刪掉,又因為

trim

標籤設定了prefix=”where”,所以需要在拼接的SQL語句前面加一個where語句

最後

trim

標籤的SQL語句被拼接成如下所示
where user_email = #{userEmail} and user_city = #{userCity}
登入後複製

choose

有時我們不想應用到所有的條件語句,而只想從中擇其一項。針對這種情況,MyBatis 提供了 choose 元素,它有點像 Java 中的 switch 語句。

<select id="findByUser" resultType="com.example.mybatis.entity.User">
        select
        id, username, user_email userEmail, user_city userCity, age
        from user        <where>
            <choose>
                <when test="username != null and username != &#39;&#39;">
                    username = #{username}                </when>
                <when test="userEmail != null and userEmail != &#39;&#39;">
                    and user_email = #{userEmail}                </when>
                <when test="userCity != null and userCity != &#39;&#39;">
                    and user_city = #{userCity}                </when>
            </choose>
        </where>
    </select>
登入後複製

###set######set 標籤用於 Update 操作,會自動根據參數選擇產生 SQL 語句。 ######介面定義如下###
public int updateUser(User user);
登入後複製
###介面對應的Mapper.xml 定義如下所示###
<update id="updateUser" parameterType="com.example.mybatis.entity.User">
       update user       <set>
           <if test="username != null and username != &#39;&#39;">
               username=#{username},           </if>
           <if test="userEmail != null and userEmail != &#39;&#39;">
               user_email=#{userEmail},           </if>
           <if test="userCity != null and userCity != &#39;&#39;">
               user_city=#{userCity},           </if>
           <if test="age != null">
              age=#{age}           </if>
       </set>
       where id=#{id}    </update>
登入後複製
#########foreach######foreach 標籤可以迭代產生一系列值######*###用於SQL 的in 語句*######

接口定义如下所示

public List<User> getUsersByIds(List<Integer> ids);
登入後複製

接口对应的 Mapper.xml 定义如下所示

<!--
        collection: 指定要遍历的集合
            默认情况下
                如果为Collection类型的,key为collection;
                如果为List类型的,key为list
                如果是数组类型,key为array
            可以通过@Param("ids")来指定key
        item: 将当前遍历的元素赋值给指定的变量
        open: 给遍历的结果添加一个开始字符
        close: 给遍历的结果添加一个结束字符
        separator: 每个元素之间的分隔符
    --><select id="getUsersByIds"
        resultType="com.example.mybatis.entity.User">
    select * from user
    where id in    <foreach collection="list" item="id" open="(" close=")" separator=",">
        #{id}    </foreach></select>
登入後複製

用于批量插入

接口定义如下所示

public int addUserList(List<User> users);
登入後複製

接口对应的 Mapper.xml 定义如下所示

<insert id="addUserList"
        parameterType="com.example.mybatis.entity.User">
    insert into user
    (username, user_email, user_city, age)
    values    <foreach item="user"  collection="list" separator=",">
        (#{user.username}, #{user.userEmail}, #{user.userCity}, #{user.age})    </foreach></insert><!--返回自增主键--><insert id="addUserList"
        parameterType="com.example.mybatis.entity.User"
        useGeneratedKeys="true"
        keyProperty="id">
    insert into user
    (username, user_email, user_city, age)
    values    <foreach item="user"  collection="list" separator=",">
        (#{user.username}, #{user.userEmail}, #{user.userCity}, #{user.age})    </foreach></insert><!--还可以这样写--><!--
    这种方式需要数据库连接属性设置allowMultiQueries=true
    这种分号分隔多个SQL还可以用于其他的批量操作,如修改、删除
--><insert id="addUserList"
        parameterType="com.example.mybatis.entity.User">
    <foreach item="user"  collection="list" separator=";">
        insert into user
        (username, user_email, user_city, age)
        values
        (#{user.username}, #{user.userEmail}, #{user.userCity}, #{user.age})    </foreach></insert><!--如果是Oracle数据库,则需要这样写--><insert id="addUserList"
        parameterType="com.example.mybatis.entity.User">
    <foreach item="user" open="begin" close="end;"  collection="list">
        insert into user
        (username, user_email, user_city, age)
        values
        (#{user.username}, #{user.userEmail}, #{user.userCity}, #{user.age});    </foreach></insert>
登入後複製

以上是學習MyBatis 動態 SQL的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:learnku.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板