#{} 和 ${} 的區別---使用 ${} 會有sql注入的問題

很簡單的一個排序字段,可是由於使用 ${} 佔位符的緣由,有sql注入的風險,相信你們平時也常常會使用這個佔位符,不知道有沒有考慮sql注入的問題,下面簡單介紹下 #{} 和 ${} 的區別以及爲何使用 ${} 會有sql注入的問題。前端

區別
#{}是一個參數佔位符,對於String類型會自動加上"",其餘類型不加。因爲Mybatis採用預編譯,其後的參數不會再進行SQL編譯,因此必定程度上防止SQL注入。
${}是一個簡單的String替換,字符串是什麼,解析就是什麼。
類如order by。假如前端傳的參數是id(假設id是String類型),對於order by #{id},對應的sql語句就是 order by 「id」;對於order by ${id},對應的sql語句則是order by id。這種狀況,當用戶傳參爲id && 1=1 的時候,就會產生難以預計的後果。
解決方法
在原實體類里加入一個map
public Map<String,String> indexMap=new HashMap<String,String>(){
{
put("spaceId","space_id"); // key爲前端傳的值,value爲數據庫對應的列值
put("optTime","opt_time");
}
};
當傳參時,判斷參數是否在map的key中,若是存在的話,就把對應的value做爲排序的依賴條件。
if(paramOptLog.getOrderBy()!=null &&Strings.isNullOrEmpty(paramOptLog.getOrderBy())){
OptLog optLog=new OptLog();
paramOptLog.setOrderBy(optLog.indexMap.getOrDefault(paramOptLog.getOrderBy(), "id"));
}
List<OptLog> list = optLogMapper.query4Page(paramOptLog);
}
總結就是經過映射,由程序員來決定 ${} 傳的參數,即將動態sql轉成靜態sql的方式能夠解決這個問題,這樣在實際調用的時候就不會有sql注入的風險了。

程序員

相關文章
相關標籤/搜索