MyBatis動(dòng)態(tài)Sql之if標(biāo)簽的用法詳解

最近在讀劉增輝老師所著的《MyBatis從入門到精通》一書,很有收獲,于是將自己學(xué)習(xí)的過程以博客形式輸出,如有錯(cuò)誤,歡迎指正,如幫助到你,不勝榮幸!

創(chuàng)新互聯(lián)專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站、外貿(mào)網(wǎng)站建設(shè)、福綿網(wǎng)絡(luò)推廣、微信小程序定制開發(fā)、福綿網(wǎng)絡(luò)營銷、福綿企業(yè)策劃、福綿品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);創(chuàng)新互聯(lián)為所有大學(xué)生創(chuàng)業(yè)者提供福綿建站搭建服務(wù),24小時(shí)服務(wù)熱線:18980820575,官方網(wǎng)址:muchs.cn

本篇博客主要講解如何使用if標(biāo)簽生成動(dòng)態(tài)的Sql,主要包含以下3個(gè)場(chǎng)景:

1.根據(jù)查詢條件實(shí)現(xiàn)動(dòng)態(tài)查詢
2.根據(jù)參數(shù)值實(shí)現(xiàn)動(dòng)態(tài)更新某些列
3.根據(jù)參數(shù)值實(shí)現(xiàn)動(dòng)態(tài)插入某些列

1. 使用if標(biāo)簽實(shí)現(xiàn)動(dòng)態(tài)查詢

假設(shè)有這樣1個(gè)需求:根據(jù)用戶的輸入條件來查詢用戶列表,如果輸入了用戶名,就根據(jù)用戶名模糊查詢,如果輸入了郵箱,就根據(jù)郵箱精確查詢,如果同時(shí)輸入了用戶名和郵箱,就用這兩個(gè)條件去匹配用戶。

首先,我們?cè)诮涌赟ysUserMapper中添加如下方法:

/**
 * 根據(jù)動(dòng)態(tài)條件查詢用戶信息
 *
 * @param sysUser
 * @return
 */
List<SysUser> selectByUser(SysUser sysUser);

然后在對(duì)應(yīng)的SysUserMapper.xml中添加如下代碼:

<select id="selectByUser" resultType="com.zwwhnly.mybatisaction.model.SysUser">
  SELECT id,
      user_name,
      user_password,
      user_email,
      create_time
  FROM sys_user
  WHERE 1 = 1
  <if test="userName != null and userName != ''">
    AND user_name LIKE CONCAT('%',#{userName},'%')
  </if>
  <if test="userEmail != null and userEmail != ''">
    AND user_email = #{userEmail}
  </if>
</select>

代碼簡單講解:

1)if標(biāo)簽的test屬性必填,該屬性值是一個(gè)符合OGNL要求的判斷表達(dá)式,一般只用true或false作為結(jié)果。

2)判斷條件property != null 或 property == null,適用于任何類型的字段,用于判斷屬性值是否為空。

3)判斷條件property != '' 或 property == '',僅適用于String類型的字段,用于判斷是否為空字符串。

4)當(dāng)有多個(gè)判斷條件時(shí),使用and或or進(jìn)行連接,嵌套的判斷可以使用小括號(hào)分組,and相當(dāng)于Java中的與(&&),or相關(guān)于Java中的或(||)。

所以上面代碼的意思就是先判斷字段是否為null,然后再判斷字段是否為空字符串。

最后,在SysUserMapperTest測(cè)試類中添加如下測(cè)試方法:

@Test
public void testSelectByUser() {
  SqlSession sqlSession = getSqlSession();
  try {
    SysUserMapper sysUserMapper = sqlSession.getMapper(SysUserMapper.class);
    // 只按用戶名查詢
    SysUser query = new SysUser();
    query.setUserName("ad");
    List<SysUser> sysUserList = sysUserMapper.selectByUser(query);
    Assert.assertTrue(sysUserList.size() > 0);
    // 只按郵箱查詢
    query = new SysUser();
    query.setUserEmail("test@mybatis.tk");
    sysUserList = sysUserMapper.selectByUser(query);
    Assert.assertTrue(sysUserList.size() > 0);
    // 同時(shí)按用戶民和郵箱查詢
    query = new SysUser();
    query.setUserName("ad");
    query.setUserEmail("test@mybatis.tk");
    sysUserList = sysUserMapper.selectByUser(query);
    // 由于沒有同時(shí)符合這兩個(gè)條件的用戶,因此查詢結(jié)果數(shù)為0
    Assert.assertTrue(sysUserList.size() == 0);
  } finally {
    sqlSession.close();
  }
}

運(yùn)行測(cè)試代碼,測(cè)試通過,輸出日志如下:

DEBUG [main] - ==> Preparing: SELECT id, user_name, user_password, user_email, create_time FROM sys_user WHERE 1 = 1 AND user_name LIKE CONCAT('%',?,'%')
DEBUG [main] - ==> Parameters: ad(String)
TRACE [main] - <== Columns: id, user_name, user_password, user_email, create_time
TRACE [main] - <== Row: 1, admin, 123456, admin@mybatis.tk, 2019-06-27 18:21:07.0
DEBUG [main] - <== Total: 1
DEBUG [main] - ==> Preparing: SELECT id, user_name, user_password, user_email, create_time FROM sys_user WHERE 1 = 1 AND user_email = ?
DEBUG [main] - ==> Parameters: test@mybatis.tk(String)
TRACE [main] - <== Columns: id, user_name, user_password, user_email, create_time
TRACE [main] - <== Row: 1001, test, 123456, test@mybatis.tk, 2019-06-27 18:21:07.0
DEBUG [main] - <== Total: 1
DEBUG [main] - ==> Preparing: SELECT id, user_name, user_password, user_email, create_time FROM sys_user WHERE 1 = 1 AND user_name LIKE CONCAT('%',?,'%') AND user_email = ?
DEBUG [main] - ==> Parameters: ad(String), test@mybatis.tk(String)
DEBUG [main] - <== Total: 0

2. 使用if標(biāo)簽實(shí)現(xiàn)動(dòng)態(tài)更新

假設(shè)有這樣1個(gè)需求:更新用戶信息的時(shí)候不能將原來有值但沒有發(fā)生變化的字段更新為空或null,即只更新有值的字段。

首先,我們?cè)诮涌赟ysUserMapper中添加如下方法:

/**
 * 根據(jù)主鍵選擇性更新用戶信息
 *
 * @param sysUser
 * @return
 */
int updateByIdSelective(SysUser sysUser);

然后在對(duì)應(yīng)的SysUserMapper.xml中添加如下代碼:

<update id="updateByIdSelective">
  UPDATE sys_user
  SET
  <if test="userName != null and userName != ''">
    user_name = #{userName},
  </if>
  <if test="userPassword != null and userPassword != ''">
    user_password = #{userPassword},
  </if>
  <if test="userEmail != null and userEmail != ''">
    user_email = #{userEmail},
  </if>
  <if test="userInfo != null and userInfo != ''">
    user_info = #{userInfo},
  </if>
  <if test="headImg != null">
    head_img = #{headImg,jdbcType=BLOB},
  </if>
  <if test="createTime != null">
    create_time = #{createTime,jdbcType=TIMESTAMP},
  </if>
  id = #{id}
  WHERE id = #{id}
</update>

最后,在SysUserMapperTest測(cè)試類中添加如下測(cè)試方法:

@Test
public void testUpdateByIdSelective() {
  SqlSession sqlSession = getSqlSession();
  try {
    SysUserMapper sysUserMapper = sqlSession.getMapper(SysUserMapper.class);
    SysUser sysUser = new SysUser();
    // 更新id=1的用戶
    sysUser.setId(1L);
    // 修改郵箱
    sysUser.setUserEmail("test@mybatis.tk");
    int result = sysUserMapper.updateByIdSelective(sysUser);
    Assert.assertEquals(1, result);
    // 查詢id=1的用戶
    sysUser = sysUserMapper.selectById(1L);
    // 修改后的名字保持不變,但是郵箱變成了新的
    Assert.assertEquals("admin", sysUser.getUserName());
    Assert.assertEquals("test@mybatis.tk", sysUser.getUserEmail());
  } finally {
    sqlSession.close();
  }
}

運(yùn)行測(cè)試代碼,測(cè)試通過,輸出日志如下:

DEBUG [main] - ==> Preparing: UPDATE sys_user SET user_email = ?, id = ? WHERE id = ?
DEBUG [main] - ==> Parameters: test@mybatis.tk(String), 1(Long), 1(Long)
DEBUG [main] - <== Updates: 1
DEBUG [main] - ==> Preparing: SELECT id, user_name, user_password, user_email, create_time FROM sys_user WHERE id = ?
DEBUG [main] - ==> Parameters: 1(Long)
TRACE [main] - <== Columns: id, user_name, user_password, user_email, create_time
TRACE [main] - <== Row: 1, admin, 123456, test@mybatis.tk, 2019-06-27 18:21:07.0
DEBUG [main] - <== Total: 1

3. 使用if標(biāo)簽實(shí)現(xiàn)動(dòng)態(tài)插入

假設(shè)有這樣1個(gè)需求:往數(shù)據(jù)庫表中插入數(shù)據(jù)的時(shí)候,如果某一列的參數(shù)值不為空,就使用傳入的值,如果傳入的參數(shù)值為空,就使用數(shù)據(jù)庫中的默認(rèn)值(通常是空),而不使用傳入的空值。

為了更好的理解該示例,我們先給sys_user表的user_email字段設(shè)置默認(rèn)值:test@mybatis.tk,Sql語句如下:

ALTER TABLE sys_user
MODIFY COLUMN user_email VARCHAR(50) NULL DEFAULT 'test@mybatis.tk'
COMMENT '郵箱'
AFTER user_password;

首先,我們?cè)诮涌赟ysUserMapper中添加如下方法:

/**
 * 根據(jù)傳入的參數(shù)值動(dòng)態(tài)插入列
 *
 * @param sysUser
 * @return
 */
int insertSelective(SysUser sysUser);

然后在對(duì)應(yīng)的SysUserMapper.xml中添加如下代碼:

<insert id="insertSelective" useGeneratedKeys="true" keyProperty="id">
  INSERT INTO sys_user(user_name, user_password,
  <if test="userEmail != null and userEmail != ''">
    user_email,
  </if>
  user_info, head_img, create_time)
  VALUES (#{userName},#{userPassword},
  <if test="userEmail != null and userEmail != ''">
    #{userEmail},
  </if>
  #{userInfo},#{headImg,jdbcType=BLOB},#{createTime,jdbcType=TIMESTAMP})
</insert>

最后,在SysUserMapperTest測(cè)試類中添加如下測(cè)試方法:

@Test
public void testInsertSelective() {
  SqlSession sqlSession = getSqlSession();
  try {
    SysUserMapper sysUserMapper = sqlSession.getMapper(SysUserMapper.class);
    SysUser sysUser = new SysUser();
    sysUser.setUserName("test-selective");
    sysUser.setUserPassword("123456");
    sysUser.setUserInfo("test info");
    sysUser.setCreateTime(new Date());
    sysUserMapper.insertSelective(sysUser);
    // 獲取剛剛插入的數(shù)據(jù)
    sysUser = sysUserMapper.selectById(sysUser.getId());
    // 因?yàn)闆]有指定userEmail,所以用的是數(shù)據(jù)庫的默認(rèn)值
    Assert.assertEquals("test@mybatis.tk", sysUser.getUserEmail());
  } finally {
    sqlSession.close();
  }
}

運(yùn)行測(cè)試代碼,測(cè)試通過,輸出日志如下:

DEBUG [main] - ==> Preparing: INSERT INTO sys_user(user_name, user_password, user_info, head_img, create_time) VALUES (?,?, ?,?,?)
DEBUG [main] - ==> Parameters: test-selective(String), 123456(String), test info(String), null, 2019-07-08 11:40:36.927(Timestamp)
DEBUG [main] - <== Updates: 1
DEBUG [main] - ==> Preparing: SELECT id, user_name, user_password, user_email, create_time FROM sys_user WHERE id = ?
DEBUG [main] - ==> Parameters: 1021(Long)
TRACE [main] - <== Columns: id, user_name, user_password, user_email, create_time
TRACE [main] - <== Row: 1021, test-selective, 123456, test@mybatis.tk, 2019-07-08 11:40:37.0
DEBUG [main] - <== Total: 1

4. 源碼

源碼地址:https://github.com/zwwhnly/mybatis-action.git,歡迎下載。

總結(jié)

以上所述是小編給大家介紹的MyBatis動(dòng)態(tài)Sql之if標(biāo)簽的用法詳解 ,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)創(chuàng)新互聯(lián)網(wǎng)站的支持!
如果你覺得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!

新聞名稱:MyBatis動(dòng)態(tài)Sql之if標(biāo)簽的用法詳解
網(wǎng)址分享:http://muchs.cn/article44/jejcee.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站導(dǎo)航、云服務(wù)器網(wǎng)站設(shè)計(jì)公司、用戶體驗(yàn)全網(wǎng)營銷推廣

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作