Mybatis基礎: #{...} 和 ${...} 的區別
MyBatis將 #{…} 解釋爲JDBC
prepared statement 的一個參數標記。而將 ${…} 解釋爲字符串替換。理解這兩者的區別是很有用的, 因爲在某些SQL語句中並不能使用參數標記(parameter
markers)。比如,我們不能在表名(table name)的位置使用參數標記。假設有下面的代碼:
-
Map<String, Object> parms = new HashMap<String, Object>();
-
parms.put("table", "foo");
-
parms.put("criteria", 37);
-
List<Object> rows = mapper.generalSelect(parms);
-
<select id="generalSelect" parameterType="map">
-
select * from ${table} where col1 = #{criteria}
-
</select>
MyBatis生成的SQL語句(prepared statement)如下所示:
-
select * from foo where col1 = ?
重要提示: 請注意,使用$
{…} (字符串替換)時可能會有SQL注入攻擊的風險。另外,字符串替換在處理複雜類型也可能常常發生問題,如日期類型。由於這些因素,我們建議您儘可能地使用 #{…} 這種方式。
要使用LIKE語句該怎麼寫?
有兩種使用LIKE的方法。(推薦使用)第一種方法是,在Java代碼中添加SQL通配符。
示例一:
-
String wildcardName = "%Smi%";
-
List<Name> names = mapper.selectLike(wildcardName);
-
<select id="selectLike">
-
select * from foo where bar like #{value}
-
</select>
第二種方式是在SQL語句中拼接通配符。這種方法相對來說安全性要低一些,因爲可能會被SQL注入攻擊。示例二:
-
String wildcardName = "Smi";
-
List<Name> names = mapper.selectLike(wildcardName);
-
<select id="selectLike">
-
select * from foo where bar like '%' || '${value}' || '%'
-
</select>
重要提示: 請注意兩種方式中 $ 和 # 的使用!
如何執行批量插入?
首先,創建一個簡單的insert語句:
-
<insert id="insertName">
-
insert into names (name) values (#{value})
-
</insert>
然後在Java代碼中像下面這樣執行批處理插入:
-
List<String> names = new ArrayList<String>();
-
names.add("Fred");
-
names.add("Barney");
-
names.add("Betty");
-
names.add("Wilma");
-
-
-
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
-
try {
-
NameMapper mapper = sqlSession.getMapper(NameMapper.class);
-
for (String name : names) {
-
mapper.insertName(name);
-
}
-
sqlSession.commit();
-
} finally {
-
sqlSession.close();
-
}
如何獲取自動生成的(主)鍵值?
insert 方法總是返回一個int值 - 這個值代表的是插入的行數。而自動生成的鍵值在 insert 方法執行完後可以被設置到傳入的參數對象中。示例:
-
<insert id="insertName" useGeneratedKeys="true" keyProperty="id">
-
insert into names (name) values (#{name})
-
</insert>
-
Name name = new Name();
-
name.setName("Fred");
-
-
int rows = mapper.insertName(name);
-
-
System.out.println("rows inserted = " + rows);
-
System.out.println("generated key value = " + name.getId());
在mapper中如何傳遞多個參數?
Java的反射機制並不能讓框架獲取到參數的名字(方法簽名中只有參數類型,可以說是爲了優化,也可以說設計就是如此,總之名字無意義), 所以MyBatis默認的命名爲: param1,param2……如果想給他們指定名稱,可以使用 @param 註解:
-
import org.apache.ibatis.annotations.Param;
-
public interface UserMapper {
-
User selectUser(@Param("username") String username,
-
@Param("hashedPassword") String hashedPassword);
-
}
然後,就可以在xml像下面這樣使用(推薦封裝爲一個Map,作爲單個參數傳遞給Mapper):
-
<select id=”selectUser” resultType=”User”>
-
select id, username, hashedPassword
-
from some_table
-
where username = #{username}
-
and hashedPassword = #{hashedPassword}
-
</select>
原文鏈接: http://blog.csdn.net/renfufei/article/details/39649707