MyBatis 问题(持续更新)
第一種寫法(1): 原符號 < <= > >= & ' " 替換符號 < <= > >= & ' " 例如:sql如下: create_date_time >= #{startTime} and create_date_time <= #{endTime}第二種寫法(2): 大于等于 <![CDATA[ >= ]]> 小于等于 <![CDATA[ <= ]]> 例如:sql如下: create_date_time <![CDATA[ >= ]]> #{startTime} and create_date_time <![CDATA[ <= ]]> #{endTime}
?2.mybatis中的#和$的區(qū)別
動態(tài) sql 是 mybatis 的主要特性之一,在mybatis中我們可以把參數(shù)傳到xml文件,由mybatis對sql及其語法進(jìn)行解析,mybatis支持使用${}和#{}。可能有些人沒有留意到,認(rèn)為${}和#{}的作用一樣,其實(shí)他們的功能相似,但還是有區(qū)別的。
對比
1、使用${}方式傳入的參數(shù),mybatis不會對它進(jìn)行特殊處理,而使用#{}傳進(jìn)來的參數(shù),mybatis默認(rèn)會將其當(dāng)成字符串。可能在賦值給如id=#{id}和id=${id}看不出多大區(qū)別,但是作為表名或字段參數(shù)時可以明顯看出,可以看看下面的例子:
假設(shè)傳入的參數(shù)為表名test
select * from #{table}; #解析后是:select * from "test"; select * from ${table}; #解析后是:select * from test; ?很明顯,前者多了字符串的引號,會失敗,后者正常查詢會成功;
所以對于傳入分組(order)字段或者排序字段(order),應(yīng)使用${},避免出現(xiàn)order by "id" 等情況。
2、#和$在預(yù)編譯處理中是不一樣的。#類似jdbc中的PreparedStatement,對于傳入的參數(shù),在預(yù)處理階段會使用?代替,比如:
select * from student where id = ?; #待真正查詢的時候即在數(shù)據(jù)庫管理系統(tǒng)中(DBMS)才會代入?yún)?shù)。 #而${}則是簡單的替換,如下: select * from student where id = 2; select * from tbl_employee where id=${id} and last_name=#{lastName} ? #Preparing: select * from tbl_employee where id=2 and last_name=? 區(qū)別:#{}:是以預(yù)編譯的形式,將參數(shù)設(shè)置到sql語句中;PreparedStatement;防止sql注入
${}:取出的值直接拼裝在sql語句中;會有安全問題;
大多情況下,我們?nèi)?shù)的值都應(yīng)該去使用#{};
原生jdbc不支持占位符的地方我們就可以使用${}進(jìn)行取值
比如分表、排序。。。;按照年份分表拆分
select * from ${year}_salary where xxx;select * from tbl_employee order by ${f_name} ${order}總結(jié)
1、能使用#{}的地方應(yīng)盡量使用#{}
2、像PreparedStatement ,#{}可以有效防止sql注入,${}則可能導(dǎo)致sql注入成功。
所謂sql注入,就是指把用戶輸入的數(shù)據(jù)拼接到sql語句后面作為sql語句的一部分執(zhí)行,例如:
select * from user where name=' "+name+" ' and password=' "+password+" ' or 'abc' = 'abc'; #那么只要用戶輸入用戶名admin和密碼123456,那么拼接出來的語句就為 select * from user where name=' admin ' and password='123456' or 'abc'= 'abc'; #這樣只要user表有數(shù)據(jù),就會返回結(jié)果,達(dá)到sql注入的目的。同樣,用戶輸入用戶名a'則 and password=' "+password+" '就會被注釋掉,也達(dá)到注入sql的目的。 ?附:
這里順帶提下防止sql注入的幾種方式(可能不止這幾種):
(1)、jdbc使用 PreparedStatement代替Statement, PreparedStatement 不僅提高了代碼的可讀性和可維護(hù)性.而且也提高了安全性,有效防止sql注入;
(2)、在程序代碼中使用正則表達(dá)式過濾參數(shù)。使用正則表達(dá)式過濾可能造成注入的符號,如' --等
(3)、在頁面輸入?yún)?shù)時也進(jìn)行字符串檢測和提交時進(jìn)行參數(shù)檢查,同樣可以使用正則表達(dá)式,不允許特殊符號出現(xiàn)。
resultType:返回值類型
別名或者全類名,如果返回的是集合,定義集合中元素的類型(而不是集合本身)。
resultMap:
外部resultMap的命名引用,resultType與resultMap不能同時使用
?
3.Mybatis緩存:(一級緩存和二級緩存)
1.默認(rèn)情況下,只有一級緩存(sqlSession級別的緩存,也成為本地緩存)開啟
2.二級緩存需要手動開啟和配置,他是基于nameSpace級別的緩存
3,.為了提高擴(kuò)展性,mybatis定義了緩存接口Cache,我們可以通過實(shí)現(xiàn)Cache接口來自定義二級緩存
一級緩存(local cache):
也即本地緩存,作用域默認(rèn)為sqlSession.當(dāng)Session flush 或者close后,該session中的所有Cache將清空
本地緩存不能被關(guān)閉,但可以調(diào)用clearCache()來清空本地緩存,或者改變緩存的作用域
mybatis3.1后可以在mybatis.xml配置本地緩存的作用域
一級緩存失效的情況
1.不同的sqlsession對應(yīng)不同的一級緩存
2.同一個sqlsession但是查詢條件不同
3.同一個sqlsession 兩次查詢期間執(zhí)行了任何一次增刪改的操作
4.同一個sqlsession 兩次查詢期間手動清空了緩存
二級緩存:
二級緩存,全局作用域緩存
二級緩存默認(rèn)不開啟,需要手動配置
mybatis提供二級緩存的接口一級實(shí)現(xiàn),緩存實(shí)現(xiàn)要求POJO實(shí)現(xiàn)serializable接口
二級緩存在sqlsession關(guān)閉或者提交后才會生效
注意:當(dāng)在一個作用域(一級緩存session或者二級緩存namespace)中進(jìn)行了C/U/D操作后,默認(rèn)該作用域下所有的select中的緩存將被clear
4.開啟mybatis 執(zhí)行sql時,參數(shù)打印
logging.level.com.xxx.xxx.payapply.mapper=DEBUG?
轉(zhuǎn)載于:https://www.cnblogs.com/weixiaotao/p/10422021.html
總結(jié)
以上是生活随笔為你收集整理的MyBatis 问题(持续更新)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 解决Web部署 svg/woff/wof
- 下一篇: sql语句(Oracle和sqlserv