Mybatis靜態挪用表名和字段名的處理辦法。本站提示廣大學習愛好者:(Mybatis靜態挪用表名和字段名的處理辦法)文章只能為提供參考,不一定能成為您想要的結果。以下是Mybatis靜態挪用表名和字段名的處理辦法正文
一向在應用Mybatis這個ORM框架,都是應用mybatis裡的一些經常使用功效。明天在項目開辟中有個營業是須要限制各個用戶對某些內外的字段查詢和某些字段能否顯示,如某張表的某些字段不讓用戶查詢到。這類情形下,就須要構建sql來靜態傳入表名、字段名了。如今對處理辦法停止下總結,願望對碰到異樣成績的同伴有些贊助。
靜態SQL是mybatis的壯大特征之一,mybatis在對sql語句停止預編譯之前,會對sql停止靜態解析,解析為一個BoundSql對象,也是在此處對靜態sql停止處置。上面讓我們先來熟習了mybatis裡#{}與${}的用法:
在靜態sql解析進程,#{}與${}的後果是紛歧樣的:
#{ } 解析為一個 JDBC 預編譯語句(prepared statement)的參數標志符。
如以下sql語句
select * from user where name = #{name};
會被解析為:
select * from user where name = ?;
可以看到#{}被解析為一個參數占位符?。
${ } 僅僅為一個純碎的 string 調換,在靜態 SQL 解析階段將會停止變量調換
如一下sql語句:
select * from user where name = ${name};
當我們傳遞參數“sprite”時,sql會解析為:
select * from user where name = "sprite";
可以看到預編譯之前的sql語句曾經不包括變量name了。
綜上所得, ${ } 的變量的調換階段是在靜態 SQL 解析階段,而 #{ }的變量的調換是在 DBMS 中。
#{}與${}的差別可以簡略總結以下:
#{}將傳入的參數當做一個字符串,會給傳入的參數加一個雙引號
${}將傳入的參數直接顯示生成在sql中,不會添加引號
#{}可以或許很年夜成都上避免sql注入,${}沒法避免sql注入
${}在預編譯之前曾經被變量調換了,這會存在sql注入的風險。以下sql
select * from ${tableName} where name = ${name}
假如傳入的參數tableName為user; delete user; --,那末sql靜態解析以後,預編譯之前的sql將變成:
select * from user; delete user; -- where name = ?;
--以後的語句將作為正文不起感化,馬上我和我的小同伴驚呆了!!!看到沒,原來的查詢語句,居然悄悄的包括了一個刪除表數據的sql,是刪除,刪除,刪除!!!主要的工作說三遍,可想而知,這個風險是有多年夜。
${}普通用於傳輸數據庫的表名、字段名等
能用#{}的處所盡可能別用${}
進入正題,經由過程下面的剖析,信任年夜家能夠曾經對若何靜態挪用表名和字段名有些思緒了。示例以下:
<select id="getUser" resultType="java.util.Map" parameterType="java.lang.String" statementType="STATEMENT"> select ${columns} from ${tableName} where COMPANY_REMARK = ${company} </select>
要完成靜態挪用表名和字段名,就不克不及應用預編譯了,需添加statementType="STATEMENT"" 。
statementType:STATEMENT(非預編譯),PREPARED(預編譯)或CALLABLE中的隨意率性一個,這就告知 MyBatis 分離應用Statement,PreparedStatement或許CallableStatement。默許:PREPARED。這裡明顯不克不及應用預編譯,要改成非預編譯。
其次,sql裡的變量取值是${xxx},不是#{xxx}。
由於${}是將傳入的參數直接顯示生成sql,如${xxx}傳入的參數為字符串數據,需在參數傳入前加上引號,如:
String name = "sprite"; name = "'" + name + "'";
以上所述是小編給年夜家引見的Mybatis靜態挪用表名和字段名的處理辦法,願望對年夜家有所贊助,假如年夜家有任何疑問請給我留言,小編會實時答復年夜家的。在此也異常感激年夜家對網站的支撐!