4 Mybatis 进阶

#和$的区别

#{ }
PreparedS tatement
无SQL注入
无法读取配置文件内容

${}
Statement
SQL注入
优先读取配置文件属性
分库分表(数据量超大)

代码实现
配置文件Student.xml(片段):

//批量删除数据
public static void batchDelete2(String[] ids)throws IOException,
SQLException{
SqlSessionFactory factory = MybatisUtils.getFactory();
SqlSession session = factory.openSession(true);
//根据传入的多个id,拼写删除sql的条件
StringBuffer buf=new StringBuffer();
for(String id:ids){
	if(buf.length()>0){
		buf.append(" or ");
}
	buf.append(" id='"+id+"' ");
}
Map map=new HashMap();
map.put("condition", buf.toString());
long deleteNum = session.delete("school.batchDelete2",map);
System.out.println("删除了"+deleteNum+" 条数据");
session.close();
}

测试代码:

public static void main(String[] args) throws IOException,SQLException {
String[] ids={"1","2","3"};
batchDelete2(ids);
}

详细分析区别:

#用于变量替换

select * from student where id = #id#
等效于
prepareStement = stmt.createPrepareStement("select * from student where
id = ?")
prepareStement.setString(1, "kc1");

最终执行的sql 是select * from student where id = ‘kc1’

$ 的作用实际上是字符串拼接

select * student where id = $id$
等效于
StringBuffer sb = new StringBuffer(256);
sb.append("select * from student where id =").append("kc1");
最终执行的sql 是select * from student where id = kc1 ,注意是没有单引号的。

如果id 字段是数字类型,那么#和$在这种情况下的用法是相同的;如果id 字段是字符串类
型,那么#和$在这种情况下的用法是不同的,使用$会报出错误。

说道这里,总结一下,什么时候用$,什么时候用#。

对于变量部分,应当使用#,这样可以有效的防止sql 注入,# 都是用到了prepareStement,
这样对效率也有一定的提升。

$只是简单的字符拼接而已,对于非变量部分,那只能使用$,实际上,在很多场合,$也是
有很多实际意义的,例如:
select * from $tableName$ 对于不同的表执行统一的查询
update $tableName$ set status = #status# 每个实体一张表,改变不同实体的状态

特别提醒一下,$只是字符串拼接, 所以要特别小心sql 注入问题。

指定默认的执行器
4 Mybatis 进阶_第1张图片

4 Mybatis 进阶_第2张图片

你可能感兴趣的:(mybatis,mybatis)