1. 程式人生 > >Mybatis框架的使用之三(條件SQL)

Mybatis框架的使用之三(條件SQL)

對上次內容的補充:上一次通過Mytatis實現了最簡單的select count(1) 查詢,返回的型別是基本的int值,實際上在使用中,查詢返回的結果也可能複雜資料型別,比如查詢所有使用者資訊,那麼返回的就可能是一個使用者的集合,這種情況下,返回型別resultType不是寫List,而是要具體到集合中的元素的型別,比如返回的是User物件集合,那麼resultType應該是User這個類。具體操作通過帶參查詢一起展示:

一、單引數SQL:

需求:通過姓名,對所有使用者進行模糊查詢

首先,我們到UserMapper的介面建立新的抽象方法:

List<User>
getUserListByName(String userName);

然後到UserMapper.xml編寫sql語句。因為依舊是查詢,所以再新建一個select標籤:

<!-- 根據使用者名稱稱查詢使用者列表(模糊查詢) -->
<!-- 依舊要注意,select標籤的id值要跟介面的抽象方法名一致! -->
<!-- resultType返回的結果是User的集合,所以是User -->
<!-- 這次出現了新的屬性 parameterType,引數的型別,這裡是字串 -->
    <select id="getUserListByName"
resultType="User" parameterType="String"> <!--JDBC中,對於引數是用?代替,mybatis則使用#{引數名},要注意引數名是跟介面中方法的形參名稱一致 ,前後兩個%則用於實現模糊查詢--> select * from smbms_user where userName like CONCAT('%',#{userName},'%') </select>

到測試類中建立測試方法:

 public void getUserListByName() {
        SqlSession sqlSession =
null; List<User> list; try { sqlSession = MyBatisUtils.getSQLSession(); //這裡直接傳實參,查詢姓名中帶"趙"字的使用者 list = sqlSession.getMapper(UserMapper.class).getUserListByName("趙"); for (User user : list) { logger.debug("UserCode:" + user.getUserCode() + "\tUserName:" + user.getUserName()); } } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } finally { MyBatisUtils.closeSqlSession(sqlSession); } }

執行測試方法,控制檯輸出資訊如下:

在這裡插入圖片描述

結果主要是這幾行:

Preparing: select * from smbms_user where userName like CONCAT(’%’,?,’%’)
查詢語句,可以看到編寫時使用的#{}已經變成了JDBC的?,因此mybatis實質就是對JDBC的封裝

Parameters: 趙(String)
引數以及型別

UserCode:zhaoyan UserName:趙燕
UserCode:zhaomin UserName:趙敏
查詢並遍歷的結果

至此,單條件(單引數)的查詢就完成了。

二、多引數SQL:

多引數的sql語句執行主要有兩個解決思路,1是有幾個條件就傳遞幾個引數,2封裝一個物件作為引數。下面分別進行說明:

1、傳遞多個引數:
這是最容易想到的方式,在JDBC中也可以通過設定多個?的方式實現多條件操作。
需求模擬:修改使用者密碼。為了方便操作這裡不進行新舊密碼匹配。
需要兩個引數,1是使用者的id值,2是新密碼
還是先建立介面的抽象方法:

//返回型別是int,表示受影響的行數
int updatePwd(@Param("id") Integer id, @Param("userPassword") String pwd);

這裡小夥伴可能會注意到,每一個引數的前面多了一個@Param的註解。原因是Mybatis實際上是用過Map的方式,通過key來獲得value。在這裡,@Param(“id”)裡的id就作為了key,而引數Integer id的id就是value,之後同理。 可能有的小夥伴會疑惑,為什麼只傳遞一個引數的時候沒有使用@Param註解,也是可以成功執行,那是因為一個引數的情況下Mybatis會自動產生一個跟value同名的key。因此實際上,即使是一個引數,規範的寫法也是應該加上@Param註解。

下面編寫Mapper檔案,這裡的需求是修改密碼,因此建立的是update標籤

<update id="updatePwd">
		//需要說明的是,#{引數名}應該是與介面方法中註解的名字一致
        UPDATE smbms_user SET userPassword=#{userPassword} where id=#{id}
    </update>

測試方法:

 public void updatePwd() {
        SqlSession sqlSession = null;
        int count = 0;
        try {
            sqlSession = MyBatisUtils.getSQLSession();
            //將id值是17的使用者的密碼修改為"666666"
            count = sqlSession.getMapper(UserMapper.class).updatePwd(17, "666666");
            //這裡出現了新的方法commit(),因為在建立sqlsession物件的時候,我們打開了事務控制,因此語句執行完畢後必須提交才能生效
            sqlSession.commit();
        } catch (Exception e) {
            e.printStackTrace();
            //如果進入了catch塊,則回滾不生效。
            sqlSession.rollback();
            count = 0;
        } finally {
            MyBatisUtils.closeSqlSession(sqlSession);
        }
        logger.debug("testUpdatePwd----------" + count);

    }

執行的結果我就不貼圖了,如果資料庫的使用者表存在id是17的使用者,且各個配置檔案沒有錯誤的話,影響的行數就是1,表示修改成功。可以重新整理表檢視。

剛才說到Mybatis的多參實際上是Map的形式,那麼我們必然也可以通過建立一個Map,用它來作為引數進行傳遞
需求分析:通過姓名以及職位id,查詢滿足條件的使用者

先貼一張表截圖:
在這裡插入圖片描述
介面方法:

    List<User> getUserListByMap(Map<String, String> userMap);

Mapper.xml語句:

//返回型別不變,只是引數型別,我們使用了Map
  <select id="getUserlistByMap" resultType="User" parameterType="Map">
		select * from smbms_user where userName like 
		   <!-- 下面每一個#{}內的名稱要與建立的Map中的key一一對應 -->
		CONCAT('%',#{userName},'%') AND  userRole = #{userRole}
	</select>

建立測試類:

 public void getUserlistByMap() {
        SqlSession sqlSession = null;
        List<User> list;
        Map<String, String> userMap = new HashMap<>();
        //map裡每一個key,都與mapper檔案SQL語句中的#{}一一對應
        userMap.put("userName", "趙");
        userMap.put("userRole", "2");
        try {
            sqlSession = MyBatisUtils.getSQLSession();
            list = sqlSession.getMapper(UserMapper.class).getUserListByMap(userMap);
            for (User user : list)
                logger.debug("UserCode:" + user.getUserCode() + "\tUserName:"
                        + user.getUserName() + "\tUserAddress:"
                        + user.getAddress() + "\tage:" + user.getAge() + "\taddress:" + user.getAddress());

        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        } finally {
            MyBatisUtils.closeSqlSession(sqlSession);
        }
    }

最終執行的結果是:
Preparing: select * from smbms_user where userName like CONCAT(’%’,?,’%’) AND userRole = ?

Parameters: 趙(String), 2(String)

UserCode:zhaomin UserName:趙敏 UserAddress:北京市昌平區天通苑3區12號樓 age:31 address:北京市昌平區天通苑3區12號樓

當然,也可以使用封裝User物件的方式。mapper檔案中parameterType型別為User,測試類中通過User user = new User()建立user物件,然後通過user.setUserName(“趙”)、user.setUserRole(2),然後將user物件作為方法的實參。

Mybatis框架的使用之四傳送門:
https://blog.csdn.net/wangduanqs/article/details/85023293