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