摘要:并且如果使用那么必須要指明值使用簡(jiǎn)單的數(shù)據(jù)類型不好使使用接口代理模式的注解也可以
一 模糊查詢的三種方式介紹屬于MyBatis的核心之一,這里面的坑比較多,大家多多看看吧
我會(huì)使用resultMap處理結(jié)果集數(shù)據(jù)
1."死數(shù)據(jù)"的模糊查詢
映射文件
Java測(cè)試代碼
@Test public void 固定條件的模糊查詢(){ SqlSession sqlSession = null; try { sqlSession = MyBatisUtils.getSqlSession(); //定位執(zhí)行 ListtempList = sqlSession.selectList(Skill.class.getName()+".listLike01"); System.out.println(tempList); } finally { MyBatisUtils.closeSqlSession(sqlSession); } }
請(qǐng)注意: 這里使用了單元測(cè)試@Test注解
圖解說(shuō)明
映射文件
Java測(cè)試代碼
@Test public void 通過(guò)Java程序完成模糊查詢(){ SqlSession sqlSession = null; try { sqlSession = MyBatisUtils.getSqlSession(); //定位執(zhí)行 String name = "%s%";// --> 拼接的字符串 ListtempList = sqlSession.selectList(Skill.class.getName()+".listLike02",name); System.out.println(tempList); } finally { MyBatisUtils.closeSqlSession(sqlSession); } }
圖解說(shuō)明
映射文件
concat 拼接字符串
Java測(cè)試代碼
@Test public void 通過(guò)SQL語(yǔ)句函數(shù)完成模糊查詢(){ SqlSession sqlSession = null; try { sqlSession = MyBatisUtils.getSqlSession(); //定位執(zhí)行 String name = "s";// --> 只是自己處理 ListtempList = sqlSession.selectList(Skill.class.getName()+".listLike03",name); System.out.println(tempList); } finally { MyBatisUtils.closeSqlSession(sqlSession); } }
圖解說(shuō)明
這里涉及到一道面試題 : MyBatis框架中#{}和${}的區(qū)別? - 請(qǐng)見附錄1
映射文件
Java測(cè)試代碼
@Test public void 模糊查詢(){//${}完成模糊查詢 SqlSession sqlSession = null; try { sqlSession = MyBatisUtils.getSqlSession(); //定位執(zhí)行 Mapmap = new HashMap (); map.put("shxt", "s");// 注意 -> 需要設(shè)置 KEY 不然無(wú)法獲取 List tempList = sqlSession.selectList(Skill.class.getName()+".listLike04",map); System.out.println(tempList); } finally { MyBatisUtils.closeSqlSession(sqlSession); } }
圖解說(shuō)明
我一般使用${}就是在設(shè)置表名或者排序的時(shí)候使用
映射文件
Java測(cè)試代碼
@Test public void 排序(){//${}完成模糊查詢 SqlSession sqlSession = null; try { sqlSession = MyBatisUtils.getSqlSession(); Mapmap = new HashMap (); map.put("shxt", "DESC"); List tempList = sqlSession.selectList(Skill.class.getName()+".order01",map); System.out.println(tempList); } finally { MyBatisUtils.closeSqlSession(sqlSession); } }
圖解說(shuō)明
附錄1 : #{}和${}的區(qū)別[以及 sql 預(yù)編譯 1.通用mybatis 中使用 sqlMap 進(jìn)行 sql 查詢時(shí),經(jīng)常需要?jiǎng)討B(tài)傳遞參數(shù),例如我們需要根據(jù)用戶的姓名來(lái)篩選用戶時(shí),sql 如下:
select * from sys_user where name="pangsir";
上述 sql 中,我們希望 name 后的參數(shù) "pangsir" 是動(dòng)態(tài)可變的,即不同的時(shí)刻根據(jù)不同的姓名來(lái)查詢用戶。在 sqlMap 的 xml 文件中使用如下的 sql 可以實(shí)現(xiàn)動(dòng)態(tài)傳遞參數(shù) name:
select * from user where name = #{name};
或者
select * from user where name = "${name}";
對(duì)于上述這種查詢情況來(lái)說(shuō),使用 #{ } 和 ${ } 的結(jié)果是相同的,但是在某些情況下,我們只能使用二者其一。
2.區(qū)別動(dòng)態(tài) SQL 是 mybatis 的強(qiáng)大特性之一,也是它優(yōu)于其他 ORM 框架的一個(gè)重要原因。mybatis 在對(duì) sql 語(yǔ)句進(jìn)行預(yù)編譯之前,會(huì)對(duì) sql 進(jìn)行動(dòng)態(tài)解析,解析為一個(gè) BoundSql 對(duì)象,也是在此處對(duì)動(dòng)態(tài) SQL 進(jìn)行處理的。
在動(dòng)態(tài) SQL 解析階段, #{ } 和 ${ } 會(huì)有不同的表現(xiàn):
#{ } 解析為一個(gè) JDBC 預(yù)編譯語(yǔ)句(prepared statement)的參數(shù)標(biāo)記符。
例如,sqlMap 中如下的 sql 語(yǔ)句
select * from user where name = #{name};
解析為:
select * from user where name = ?;
一個(gè) #{ } 被解析為一個(gè)參數(shù)占位符 ? ,使用Jdbc的預(yù)處理對(duì)象對(duì)數(shù)據(jù)進(jìn)行處理.
然而 , ${ } 僅僅為一個(gè)純碎的 string 替換,在動(dòng)態(tài) SQL 解析階段將會(huì)進(jìn)行變量替換.
例如,sqlMap 中如下的 sql
select * from user where name = "${name}";
當(dāng)我們傳遞的參數(shù)為 "pangsir" 時(shí),上述 sql 的解析為:
select * from user where name = "pangsir";
預(yù)編譯之前的 SQL 語(yǔ)句已經(jīng)不包含變量 name 了。
綜上所得, ${ } 的變量的替換階段是在動(dòng)態(tài) SQL 解析階段,而 #{ }的變量的替換是在 DBMS 中。
3.使用規(guī)則 3.1 能使用 #{ } 的地方就用 #{ }首先這是為了性能考慮的,相同的預(yù)編譯 sql 可以重復(fù)利用。
其次,${ } 在預(yù)編譯之前已經(jīng)被變量替換了,這會(huì)存在 sql 注入問(wèn)題。例如,如下的 sql,
案例說(shuō)明
select * from ${tableName} where name = #{name}
假如,我們的參數(shù) tableName 為 user; delete user; --,那么 SQL 動(dòng)態(tài)解析階段之后,預(yù)編譯之前的 sql 將變?yōu)?/p>
select * from user; delete user; -- where name = ?;
-- 之后的語(yǔ)句將作為注釋,不起作用,因此本來(lái)的一條查詢語(yǔ)句偷偷的包含了一個(gè)刪除表數(shù)據(jù)的 SQL!
3.2 表名作為變量時(shí),必須使用 ${ }這是因?yàn)?,表名是字符串,使?sql 占位符替換字符串時(shí)會(huì)帶上單引號(hào) "",這會(huì)導(dǎo)致 sql 語(yǔ)法錯(cuò)誤,例如:
select * from #{tableName} where name = #{name};
預(yù)編譯之后的sql 變?yōu)椋?/p>
select * from ? where name = ?;
假設(shè)我們傳入的參數(shù)為 tableName = "user" , name = "pangsir",那么在占位符進(jìn)行變量替換后,sql 語(yǔ)句變?yōu)?/p>
select * from "user" where name="pangsir";
上述 sql 語(yǔ)句是存在語(yǔ)法錯(cuò)誤的,表名不能加單引號(hào) ""(注意,反引號(hào) ``是可以的)。
并且,如果使用${}那么必須要指明KEY值,使用簡(jiǎn)單的數(shù)據(jù)類型不好使,使用接口代理模式的@Param注解也可以
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/70310.html
摘要:附轉(zhuǎn)義字符第二種方法因?yàn)檫@個(gè)是格式的,所以不允許出現(xiàn)類似這樣的字符,但是都可以使用符號(hào)進(jìn)行說(shuō)明,將此類符號(hào)不進(jìn)行解析你的可以寫成這個(gè)文件示例代碼 動(dòng)態(tài)SQL語(yǔ)句是核心之一,這里我們通過(guò)幾個(gè)示例來(lái)演示 一 多條件查詢專題 1.通過(guò)恒等式完成動(dòng)態(tài)SQL語(yǔ)句 涉及到if標(biāo)簽 ...
摘要:說(shuō)在前面的話命名空間暫時(shí)約定持久化類實(shí)體的類名的全路徑一簡(jiǎn)單查詢結(jié)果集處理查詢結(jié)果集處理為類型字段作為中的值映射文件命名空間唯一的不能重復(fù)結(jié)果集處理后變成類型當(dāng)你傳遞的是一個(gè)簡(jiǎn)單的數(shù)據(jù)類型的形參的時(shí)候那么你的值 說(shuō)在前面的話 : 命名空間暫時(shí)約定-持久化類(實(shí)體Bean)的類名的全路徑 com.shxt.model.Skill 一 簡(jiǎn)單查詢結(jié)果集處理 1.查詢結(jié)果集處理為Map類型 ...
摘要:回顧上節(jié)課我們完成了的環(huán)境搭建核心配置文件映射文件的執(zhí)行過(guò)程如何執(zhí)行定制的語(yǔ)句我們測(cè)試的是死的數(shù)據(jù)那么下面我們使用容器傳遞動(dòng)態(tài)的數(shù)據(jù)添加操作傳遞數(shù)據(jù)專題通過(guò)傳遞數(shù)據(jù)映射文件代碼傳遞參數(shù)數(shù)據(jù)的類型或者提供額內(nèi)置類型映射中的獲取對(duì)應(yīng)的值 回顧: 上節(jié)課我們完成了MyBatis的環(huán)境搭建核心配置文件映射文件API的執(zhí)行過(guò)程如何執(zhí)行定制的SQL語(yǔ)句 我們測(cè)試的是死的數(shù)據(jù),那么下面我們使用容器傳...
摘要:文件知識(shí)點(diǎn)修飾類不能被基礎(chǔ)修飾方法不能被重寫修改變量常量不允許進(jìn)行實(shí)例化靜態(tài)代碼塊只是加載一次加載核心配置文件失敗圖解說(shuō)明加載屬性文件新建的根目錄下修改核心配置文件加載屬性文件配置數(shù)據(jù)庫(kù)的環(huán)境事務(wù)管理器保證數(shù)據(jù)的完整性 MyBatisUtils.java 文件 /** * 知識(shí)點(diǎn): * final 修飾類 : 不能被基礎(chǔ) * 修飾方法 : 不能被重寫 * 修改變量 : 常量 ...
閱讀 2390·2021-11-24 10:31
閱讀 3443·2021-11-23 09:51
閱讀 2254·2021-11-15 18:11
閱讀 2405·2021-09-02 15:15
閱讀 2465·2019-08-29 17:02
閱讀 2299·2019-08-29 15:04
閱讀 846·2019-08-29 12:27
閱讀 2870·2019-08-28 18:15