問題
在這里舉一個例子,比如我要做一個多條件模糊查詢,用戶輸入的時候有可能輸入一個條件,也有可能輸入兩個條件,這時執行查詢的sql語句就不確定了,但可以用動態拼接sql語句來解決這個問題。
解決方法
1.就拿我上面的那個多條件模糊查詢為例,第一步是拼接sql語句,先定義一個通用的sql語句,String sql = "select * from user where 1 = 1 ";這里添加where 1= 1是一個小技巧,方便后面sql語句的拼接。
String sql = "select * from user where 1 = 1 ";
StringBuilder sb = new StringBuilder(sql);//創建一個StringBuilder並先把定義的通用sql放進去
2.在這里我用一個map集合將條件查詢的三個參數在servlet中獲取了,接下來遍歷map集合判斷對應的屬性是否有值,如果有值可以拼接到剛才定義的通用sql語句后面
//遍歷map看是否有屬性,condition是一個把jsp頁面傳遞過來輸入數據封裝的map集合
Set<String> keySet = condition.keySet();
//定義參數集合
List<Object> params = new ArrayList<Object>();
for (String key : keySet) {
//排除分頁條件參數
if ("currentPage".equals(key)||"rows".equals(key)){
continue;//結束當前循環
}
String value = condition.get(key)[0];
//判斷value是否有值
if (value != null && !"".equals(value)){
//動態拼接sql
sb.append(" and "+key+" like ? ");
params.add("%"+value+"%");//加?的值
}
}
3.執行sql,執行時需要參數,這又是一個問題,我得解決方法時定義了一個list集合,用於存儲參數的值value,到最后執行寫進去,由於是個list集合,可以直接用list.toArray轉化為參數數組寫進去
return template.query(sb.toString(),new BeanPropertyRowMapper<User>(User.class),params.toArray());
非常重要的注意事項
- 拼接sql的時候一定要注意空格,盡量多留幾個空格,否則sql拼接后報錯了
- 拼接好的sql需要使用toString將StringBuilder轉化為String類型,參數直接使用toArray()將list集合轉化為參數數組
整體
public List<User> findByPage(Map<String, String[]> condition) {
String sql = "select * from user where 1 = 1 ";
StringBuilder sb = new StringBuilder(sql);
//遍歷map看是否有屬性
Set<String> keySet = condition.keySet();
//定義參數集合
List<Object> params = new ArrayList<Object>();
for (String key : keySet) {
//排除分頁條件參數
if ("currentPage".equals(key)||"rows".equals(key)){
continue;//結束當前循環
}
String value = condition.get(key)[0];
//判斷value是否有值
if (value != null && !"".equals(value)){
//動態拼接sql
sb.append(" and "+key+" like ? ");
params.add("%"+value+"%");//加?的值
}
}
return template.query(sb.toString(),new BeanPropertyRowMapper<User>(User.class),params.toArray());
}