Mybatis 將table表名作為參數(shù)傳入操作
使用 $ 符
如在mapper.xml里面的使用:
在mapper層就把這個(gè)表名當(dāng)做普通的參數(shù)傳入即可:
同理,其實(shí)如果真的使用了$ ,在不考慮安全的范疇里面,也可以把一些手動(dòng)拼接的sql語句作為參數(shù)傳入。
補(bǔ)充知識(shí):MyBatis動(dòng)態(tài)傳入表名,字段名參數(shù)的解決辦法--用于分表--表名是動(dòng)態(tài)的
一直在使用Mybatis這個(gè)ORM框架,都是使用mybatis里的一些常用功能。今天在項(xiàng)目開發(fā)中有個(gè)業(yè)務(wù)是需要限制各個(gè)用戶對(duì)某些表里的字段查詢以及某些字段是否顯示,如某張表的某些字段不讓用戶查詢到。這種情況下,就需要構(gòu)建sql來動(dòng)態(tài)傳入表名、字段名了。現(xiàn)在對(duì)解決方法進(jìn)行下總結(jié),希望對(duì)遇到同樣問題的伙伴有些幫助。
動(dòng)態(tài)SQL是mybatis的強(qiáng)大特性之一,mybatis在對(duì)sql語句進(jìn)行預(yù)編譯之前,會(huì)對(duì)sql進(jìn)行動(dòng)態(tài)解析,解析為一個(gè)BoundSql對(duì)象,也是在此處對(duì)動(dòng)態(tài)sql進(jìn)行處理。下面讓我們先來熟悉下mybatis里#{}與${}的用法:
在動(dòng)態(tài)sql解析過程,#{}與${}的效果是不一樣的:
#{ } 解析為一個(gè) JDBC 預(yù)編譯語句(prepared statement)的參數(shù)標(biāo)記符。
如以下sql語句
select * from user where name = #{name};
會(huì)被解析為:
select * from user where name = ?;
可以看到#{}被解析為一個(gè)參數(shù)占位符?。
${ } 僅僅為一個(gè)純碎的 string 替換,在動(dòng)態(tài) SQL 解析階段將會(huì)進(jìn)行變量替換
如以下sql語句:
select * from user where name = ${name};
當(dāng)我們傳遞參數(shù)“sprite”時(shí),sql會(huì)解析為:
select * from user where name = 'sprite';
可以看到預(yù)編譯之前的sql語句已經(jīng)不包含變量name了。
綜上所得, ${ } 的變量的替換階段是在動(dòng)態(tài) SQL 解析階段,而 #{ }的變量的替換是在 DBMS 中。
#{}與${}的區(qū)別可以簡(jiǎn)單總結(jié)如下:
#{}將傳入的參數(shù)當(dāng)成一個(gè)字符串,會(huì)給傳入的參數(shù)加一個(gè)雙引號(hào)
${}將傳入的參數(shù)直接顯示生成在sql中,不會(huì)添加引號(hào)
#{}能夠很大程度上防止sql注入,${}無法防止sql注入
${}在預(yù)編譯之前已經(jīng)被變量替換了,這會(huì)存在sql注入的風(fēng)險(xiǎn)。如下sql
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 = ?;
--之后的語句將作為注釋不起作用,頓時(shí)我和我的小伙伴驚呆了!!!看到?jīng)],本來的查詢語句,竟然偷偷的包含了一個(gè)刪除表數(shù)據(jù)的sql,是刪除,刪除,刪除!!!重要的事情說三遍,可想而知,這個(gè)風(fēng)險(xiǎn)是有多大。
${}一般用于傳輸數(shù)據(jù)庫的表名、字段名等
能用#{}的地方盡量別用${}
進(jìn)入正題,通過上面的分析,相信大家可能已經(jīng)對(duì)如何動(dòng)態(tài)調(diào)用表名和字段名有些思路了。示例如下:
<select resultType='java.util.Map' parameterType='java.lang.String' statementType='STATEMENT'> select ${columns} from ${tableName} where COMPANY_REMARK = ${company} </select>
要實(shí)現(xiàn)動(dòng)態(tài)調(diào)用表名和字段名,就不能使用預(yù)編譯了,需添加statementType='STATEMENT'' 。
statementType:STATEMENT(非預(yù)編譯),PREPARED(預(yù)編譯)或CALLABLE中的任意一個(gè),這就告訴 MyBatis 分別使用Statement,PreparedStatement或者CallableStatement。默認(rèn):PREPARED。這里顯然不能使用預(yù)編譯,要改成非預(yù)編譯。
其次,sql里的變量取值是${xxx},不是#{xxx}。
因?yàn)?{}是將傳入的參數(shù)直接顯示生成sql,如${xxx}傳入的參數(shù)為字符串?dāng)?shù)據(jù),需在參數(shù)傳入前加上引號(hào),如:
String name = 'sprite';
name = '’' + name + '’';
mybatis動(dòng)態(tài)調(diào)用表名和字段名,還可以應(yīng)用于日志的收集上,如數(shù)據(jù)庫的日志表,每隔一個(gè)月動(dòng)態(tài)建一個(gè)日志表,表名前綴相同(如log_201610,log_201611等),這樣實(shí)現(xiàn)日志的分月分表存儲(chǔ),方便日志的分析。
以上這篇Mybatis 將table表名作為參數(shù)傳入操作就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持好吧啦網(wǎng)。
相關(guān)文章:
1. 關(guān)于Oracle中sqlldr的用法大全2. 探討SQL Server 2005.NET CLR編程3. 淺談如何將Oracle導(dǎo)出到XML文件4. [Oracle]淺談保證安全性的策略和方法5. 使用SQL語句快速獲取SQL Server數(shù)據(jù)字典6. SQL Server中, DateTime (日期)型操作7. Oracle數(shù)據(jù)庫中的字符處理技巧總結(jié)8. Microsoft SQL Server 查詢處理器的內(nèi)部機(jī)制與結(jié)構(gòu)(1)9. SQL Server 2000企業(yè)版安裝教程10. MySQL修改字符集的實(shí)戰(zhàn)教程
