mybatis學習筆記(8)-動態sql

mybatis學習筆記(8)-動態sql

標籤: mybatisjava


[TOC]mysql


mybatis核心,對sql語句進行靈活操做,經過表達式進行判斷,對sql進行靈活拼接、組裝。git

if判斷

  • mapper.xml
<!-- 用戶信息綜合查詢
    #{userCustom.sex}:取出pojo包裝對象中性別值
    ${userCustom.username}:取出pojo包裝對象中用戶名稱
 -->
<select id="findUserList" parameterType="com.iot.mybatis.po.UserQueryVo"
        resultType="com.iot.mybatis.po.UserCustom">
    SELECT * FROM user
    <!--  where 能夠自動去掉條件中的第一個and -->
    <where>
        <if test="userCustom!=null">
            <if test="userCustom.sex!=null and userCustom.sex != '' ">
               AND user.sex=#{userCustom.sex}
            </if>
            <if test="userCustom.username!=null and userCustom.username != '' ">
               AND user.username LIKE '%${userCustom.username}%'
            </if>
        </if>
    </where>


</select>

<!-- 用戶信息綜合查詢總數
    parameterType:指定輸入類型和findUserList同樣
    resultType:輸出結果類型
-->
<select id="findUserCount" parameterType="com.iot.mybatis.po.UserQueryVo" resultType="int">
    SELECT count(*) FROM user
    <where>
        <if test="userCustom!=null">
            <if test="userCustom.sex!=null and userCustom.sex != '' ">
                AND user.sex=#{userCustom.sex}
            </if>
            <if test="userCustom.username!=null and userCustom.username != '' ">
                AND user.username LIKE '%${userCustom.username}%'
            </if>
        </if>
    </where>
</select>
  • 測試結果

1.註釋掉testFindUserList()方法中的userCustom.setUsername("張三");github

//因爲這裏使用動態sql,若是不設置某個值,條件不會拼接在sql中
userCustom.setSex("1");
//userCustom.setUsername("張三");
userQueryVo.setUserCustom(userCustom);

輸出sql

DEBUG [main] - Checking to see if class com.iot.mybatis.mapper.UserMapper matches criteria [is assignable to Object]
DEBUG [main] - Checking to see if class com.iot.mybatis.mapper.UserMapperTest matches criteria [is assignable to Object]
DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Created connection 352359770.
DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@1500955a]
DEBUG [main] - ==>  Preparing: SELECT * FROM user WHERE user.sex=? 
DEBUG [main] - ==> Parameters: 1(String)
DEBUG [main] - <==      Total: 6
[User [id=10, username=張三, sex=1, birthday=Thu Jul 10 00:00:00 CST 2014, address=北京市], User [id=16, username=張小明, sex=1, birthday=null, address=河南鄭州], User [id=22, username=陳小明, sex=1, birthday=null, address=河南鄭州], User [id=24, username=張三丰, sex=1, birthday=null, address=河南鄭州], User [id=25, username=陳小明, sex=1, birthday=null, address=河南鄭州], User [id=28, username=王小軍, sex=1, birthday=Tue Feb 23 00:00:00 CST 2016, address=河南鄭州]]

能夠看到sql語句爲reparing: SELECT * FROM user WHERE user.sex=? ,沒有username的部分數組

2.userQueryVo設爲null,則userCustom爲nullmybatis

//List<UserCustom> list = userMapper.findUserList(userQueryVo);
List<UserCustom> list = userMapper.findUserList(null);

輸出app

DEBUG [main] - ==>  Preparing: SELECT * FROM user 
DEBUG [main] - ==> Parameters: 
DEBUG [main] - <==      Total: 9
[User [id=1, username=王五, sex=2, birthday=null, address=null], User [id=10, username=張三, sex=1, birthday=Thu Jul 10 00:00:00 CST 2014, address=北京市], User [id=16, username=張小明, sex=1, birthday=null, address=河南鄭州], User [id=22, username=陳小明, sex=1, birthday=null, address=河南鄭州], User [id=24, username=張三丰, sex=1, birthday=null, address=河南鄭州], User [id=25, username=陳小明, sex=1, birthday=null, address=河南鄭州], User [id=26, username=王五, sex=null, birthday=null, address=null], User [id=27, username=王大軍, sex=2, birthday=Tue Feb 23 00:00:00 CST 2016, address=河南鄭州], User [id=28, username=王小軍, sex=1, birthday=Tue Feb 23 00:00:00 CST 2016, address=河南鄭州]]

能夠看到sql語句變爲了SELECT * FROM user學習

sql片斷(重點)

將上邊實現的動態sql判斷代碼塊抽取出來,組成一個sql片斷。其它的statement中就能夠引用sql片斷。測試

  • 定義sql片斷
<!-- 定義sql片斷
id:sql片斷的惟 一標識

經驗:是基於單表來定義sql片斷,這樣話這個sql片斷可重用性才高
在sql片斷中不要包括 where
 -->
<sql id="query_user_where">
    <if test="userCustom!=null">
        <if test="userCustom.sex!=null and userCustom.sex!=''">
            AND user.sex = #{userCustom.sex}
        </if>
        <if test="userCustom.username!=null and userCustom.username!=''">
            AND user.username LIKE '%${userCustom.username}%'
        </if>
    </if>
</sql>
  • 引用sql片斷
<!-- 用戶信息綜合查詢
    #{userCustom.sex}:取出pojo包裝對象中性別值
    ${userCustom.username}:取出pojo包裝對象中用戶名稱
 -->
<select id="findUserList" parameterType="com.iot.mybatis.po.UserQueryVo"
        resultType="com.iot.mybatis.po.UserCustom">
    SELECT * FROM user
    <!--  where 能夠自動去掉條件中的第一個and -->
    <where>
        <!-- 引用sql片斷 的id,若是refid指定的id不在本mapper文件中,須要前邊加namespace -->
        <include refid="query_user_where"></include>
        <!-- 在這裏還要引用其它的sql片斷  -->
    </where>
</select>

foreach標籤

向sql傳遞數組或List,mybatis使用foreach解析

在用戶查詢列表和查詢總數的statement中增長多個id輸入查詢。兩種方法,sql語句以下:

  • SELECT * FROM USER WHERE id=1 OR id=10 OR id=16
  • SELECT * FROM USER WHERE id IN(1,10,16)

一個使用OR,一個使用IN

  • 在輸入參數類型中添加List<Integer> ids傳入多個id
public class UserQueryVo {

    //傳入多個id
    private List<Integer> ids;
    
    getter、setter方法
    。。。
}
  • 修改mapper.xml
<if test="ids!=null">
    <!-- 使用 foreach遍歷傳入ids
    collection:指定輸入 對象中集合屬性
    item:每一個遍歷生成對象中
    open:開始遍歷時拼接的串
    close:結束遍歷時拼接的串
    separator:遍歷的兩個對象中須要拼接的串
     -->
    <!-- 使用實現下邊的sql拼接:
     AND (id=1 OR id=10 OR id=16)
     -->
    <foreach collection="ids" item="user_id" open="AND (" close=")" separator="or">
        <!-- 每一個遍歷須要拼接的串 -->
        id=#{user_id}
    </foreach>
    
    <!-- 實現  「 and id IN(1,10,16)」拼接 -->
    <!-- <foreach collection="ids" item="user_id" open="and id IN(" close=")" separator=",">
        每一個遍歷須要拼接的串
        #{user_id}
    </foreach> -->

</if>
  • 測試代碼

testFindUserList中加入

//傳入多個id
List<Integer> ids = new ArrayList<Integer>();
ids.add(1);
ids.add(10);
ids.add(16);
//將ids經過userQueryVo傳入statement中
userQueryVo.setIds(ids);

做者@brianway更多文章:我的網站 | CSDN | oschina

相關文章
相關標籤/搜索