1. 程式人生 > >mybatis中的.xml檔案總結--mybatis的動態sql

mybatis中的.xml檔案總結--mybatis的動態sql

https://www.cnblogs.com/xiaoxi/p/6406504.html

resultMap

resultType可以指定pojo將查詢結果對映為pojo,但需要pojo的屬性名和sql查詢的列名一致方可對映成功。

如果sql查詢欄位名和pojo的屬性名不一致,可以通過resultMap將欄位名和屬性名作一個對應關係,能將查詢結果對映到pojo物件中。

ResultMap可以將查詢結果對映為複雜型別的pojo,比如在查詢結果中包括pojo和list實現一對一查詢和一對多查詢。

動態sql

If

注意要做不等於空字串校驗。

Foreach

向sql傳遞陣列或者list,mybatis使用foreach進行解析。

//傳遞多個使用者id

Private List<Integer> ids;

Sql片段

將重複的sql提取出來,包括重複的where條件,使用include引用。

 

 

如果引用其它mapper.xml的sql片段,則在引用時需要加上namespase

 mybatis 的動態sql語句基於OGNL表示式的。可以方便的在 sql 語句中實現某些邏輯. 總體說來mybatis 動態SQL 語句主要有以下幾類:
  1. if 語句 (簡單的條件判斷)
  2. choose (when,otherwize) ,相當於java 語言中的 switch ,與 jstl 中的choose 很類似.
  3. trim

(對包含的內容加上 prefix,或者 suffix 等,字首,字尾)
  4. where (主要是用來簡化sql語句中where條件判斷的,能智慧的處理 and or ,不必擔心多餘導致語法錯誤)
  5. set (主要用於更新時)
  6. foreach (在實現 mybatis in 語句查詢時特別有用)
下面分別介紹這幾種處理方式

1、mybatis if語句處理

複製程式碼

<select id="dynamicIfTest" parameterType="Blog" resultType="Blog">
    select * from t_blog where 1 = 1
    <if test="title != null">
        and title = #{title}
    </if>
    <if test="content != null">
        and content = #{content}
    </if>
    <if test="owner != null">
        and owner = #{owner}
    </if>
</select>

複製程式碼

解析

  如果你提供了title引數,那麼就要滿足title=#{title},同樣如果你提供了Content和Owner的時候,它們也需要滿足相應的條件,之後就是返回滿足這些條件的所有Blog,這是非常有用的一個功能。

  以往我們使用其他型別框架或者直接使用JDBC的時候, 如果我們要達到同樣的選擇效果的時候,我們就需要拼SQL語句,這是極其麻煩的,比起來,上述的動態SQL就要簡單多了。

2、choose (when,otherwize) ,相當於java 語言中的 switch ,與 jstl 中的choose 很類似

複製程式碼

<select id="dynamicChooseTest" parameterType="Blog" resultType="Blog">
    select * from t_blog where 1 = 1 
    <choose>
        <when test="title != null">
            and title = #{title}
        </when>
        <when test="content != null">
            and content = #{content}
        </when>
        <otherwise>
            and owner = "owner1"
        </otherwise>
    </choose>
</select>

複製程式碼

     when元素表示當when中的條件滿足的時候就輸出其中的內容,跟JAVA中的switch效果差不多的是按照條件的順序,當when中有條件滿足的時候,就會跳出choose,即所有的when和otherwise條件中,只有一個會輸出,當所有的我很條件都不滿足的時候就輸出otherwise中的內容。所以上述語句的意思非常簡單,當title!=null的時候就輸出and titlte = #{title},不再往下判斷條件,當title為空且content!=null的時候就輸出and content = #{content},當所有條件都不滿足的時候就輸出otherwise中的內容。

3、trim (對包含的內容加上 prefix,或者 suffix 等,字首,字尾)

複製程式碼

<select id="dynamicTrimTest" parameterType="Blog" resultType="Blog">
    select * from t_blog 
    <trim prefix="where" prefixOverrides="and |or">
        <if test="title != null">
            title = #{title}
        </if>
        <if test="content != null">
            and content = #{content}
        </if>
        <if test="owner != null">
            or owner = #{owner}
        </if>
    </trim>
</select>

複製程式碼

    trim元素的主要功能是可以在自己包含的內容前加上某些字首也可以在其後加上某些字尾,與之對應的屬性是prefix和suffix;可以把包含內容的首部某些內容覆蓋,即忽略,也可以把尾部的某些內容覆蓋,對應的屬性是prefixOverrides和suffixOverrides;正因為trim有這樣的功能,所以我們也可以非常簡單的利用trim來代替where元素的功能。

trim標記是一個格式化的標記,可以完成set或者是where標記的功能,如下程式碼:

複製程式碼

select * from user 
<trim prefix="WHERE" prefixoverride="AND |OR">
    <if test="name != null and name.length()>0"> 
        AND name=#{name}
    </if>
    <if test="gender != null and gender.length()>0"> 
        AND gender=#{gender}
    </if>
</trim>

複製程式碼

假如說name和gender的值都不為null的話列印的SQL為:select * from user where    name = 'xx' and gender = 'xx'

在紅色標記的地方是不存在第一個and的,上面兩個屬性的意思如下:

prefix:字首      

prefixoverride:去掉第一個and或者是or

複製程式碼

update user
<trim prefix="set" suffixoverride="," suffix=" where id = #{id} ">
    <if test="name != null and name.length()>0">
        name=#{name} ,
    </if>
    <if test="gender != null and gender.length()>0">
        gender=#{gender} ,  
    </if>
</trim>

複製程式碼

假如說name和gender的值都不為null的話列印的SQL為:update user set name='xx' , gender='xx'     where id='x'

在紅色標記的地方不存在逗號,而且自動加了一個set字首和where字尾,上面三個屬性的意義如下,其中prefix意義如上:

suffixoverride:去掉最後一個逗號(也可以是其他的標記,就像是上面字首中的and一樣)

suffix:字尾

4、where (主要是用來簡化sql語句中where條件判斷的,能智慧的處理 and or 條件)

複製程式碼

<select id="dynamicWhereTest" parameterType="Blog" resultType="Blog">
    select * from t_blog 
    <where>
        <if test="title != null">
            title = #{title}
        </if>
        <if test="content != null">
            and content = #{content}
        </if>
        <if test="owner != null">
            and owner = #{owner}
        </if>
    </where>
</select>

複製程式碼

     where元素的作用是會在寫入where元素的地方輸出一個where,另外一個好處是你不需要考慮where元素裡面的條件輸出是什麼樣子的,MyBatis會智慧的幫你處理,如果所有的條件都不滿足那麼MyBatis就會查出所有的記錄,如果輸出後是and 開頭的,MyBatis會把第一個and忽略,當然如果是or開頭的,MyBatis也會把它忽略;此外,在where元素中你不需要考慮空格的問題,MyBatis會智慧的幫你加上。像上述例子中,如果title=null, 而content != null,那麼輸出的整個語句會是select * from t_blog where content = #{content},而不是select * from t_blog where and content = #{content},因為MyBatis會智慧的把首個and 或 or 給忽略。

5、set (主要用於更新時) 

複製程式碼

<update id="dynamicSetTest" parameterType="Blog">
    update t_blog
    <set>
        <if test="title != null">
            title = #{title},
        </if>
        <if test="content != null">
            content = #{content},
        </if>
        <if test="owner != null">
            owner = #{owner}
        </if>
    </set>
    where id = #{id}
</update>

複製程式碼

     set元素主要是用在更新操作的時候,它的主要功能和where元素其實是差不多的,主要是在包含的語句前輸出一個set,然後如果包含的語句是以逗號結束的話將會把該逗號忽略,如果set包含的內容為空的話則會出錯。有了set元素我們就可以動態的更新那些修改了的欄位。

6、foreach (在實現 mybatis in 語句查詢時特別有用)

foreach的主要用在構建in條件中,它可以在SQL語句中進行迭代一個集合。foreach元素的屬性主要有item,index,collection,open,separator,close。

(1)item表示集合中每一個元素進行迭代時的別名。

(2)index指定一個名字,用於表示在迭代過程中,每次迭代到位置。

(3)open表示該語句以什麼開始。

(4)separator表示在每次進行迭代之間以什麼符號作為分隔符。

(5)close表示以什麼結束。

在使用foreach的時候最關鍵的也是最容易出錯的就是collection屬性,該屬性是必須指定的,但是在不同情況下,該屬性的值是不一樣的,主要有一下3種情況:

(1)如果傳入的是單引數引數型別是一個List的時候,collection屬性值為list

(2)如果傳入的是單引數且引數型別是一個array陣列的時候,collection的屬性值為array

(3)如果傳入的引數是多個的時候,我們就需要把它們封裝成一個Map了,當然單引數也可以封裝成map,實際上如果你在傳入引數的時候,在MyBatis裡面也是會把它封裝成一個Map的,map的key就是引數名,所以這個時候collection屬性值就是傳入的List或array物件在自己封裝的map裡面的key。

6.1、單引數List的型別

<select id="dynamicForeachTest" resultType="com.mybatis.entity.User">
    select * from t_user where id in
    <foreach collection="list" index="index" item="item" open="(" separator="," close=")">
        #{item}
    </foreach>
</select>

上述collection的值為list,對應的Mapper是這樣的:

/**mybatis Foreach測試 */
public List<User> dynamicForeachTest(List<Integer> ids); 

測試程式碼:

複製程式碼

@Test
public void dynamicForeachTest() {
    SqlSession sqlSession = sqlSessionFactory.openSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    List<Integer> ids = new ArrayList<Integer>();
    ids.add(1);
    ids.add(2);
    ids.add(6);
    List<User> userList = mapper.dynamicForeachTest(ids);
    for (User user : userList){
        System.out.println(user);
    }
    sqlSession.close();
}

複製程式碼

6.2、陣列型別的引數

<select id="dynamicForeach2Test" resultType="com.mybatis.entity.User">
    select * from t_user where id in
    <foreach collection="array" index="index" item="item" open="(" separator="," close=")">
        #{item}
    </foreach>
</select>

對應mapper:

public List<User> dynamicForeach2Test(int[] ids);  

測試程式碼:

複製程式碼

@Test
public void dynamicForeach2Test() {
    SqlSession sqlSession = sqlSessionFactory.openSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    int[] ids = {1,2,6};
    List<User> userList = mapper.dynamicForeach2Test(ids);
    for (User user : userList){
        System.out.println(user);
    }
    sqlSession.close();
}

複製程式碼

6.3、Map型別的引數

<select id="dynamicForeach3Test" resultType="com.mybatis.entity.User">
    select * from t_user where username like '%${username}%' and id in
    <foreach collection="ids" index="index" item="item" open="(" separator="," close=")">
        #{item}
    </foreach>
</select>

mapper 應該是這樣的介面:

/**mybatis Foreach測試 */
public List<User> dynamicForeach3Test(Map<String, Object> params); 

測試方法:

複製程式碼

@Test
public void dynamicForeach3Test() {
    SqlSession sqlSession = sqlSessionFactory.openSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    List<Integer> ids = new ArrayList<Integer>();
    ids.add(1);
    ids.add(2);
    ids.add(6);
    Map map =new HashMap();
    map.put("username", "小");
    map.put("ids", ids);
    List<User> userList = mapper.dynamicForeach3Test(map);
    System.out.println("------------------------");
    for (User user : userList){
        System.out.println(user);
    }
    sqlSession.close();
}

複製程式碼

通過以上方法,就能完成一般的mybatis 的 動態SQL 語句.最常用的就是  if where foreach這幾個,一定要重點掌握.