Map传参
多个参数尽量使用Map
比起规定类对象参数,Map实际把参数变成了灵活的参数,不固定死参数,想传什么传什么
@Test
public void MapAddTest(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
Map<String,Object> map = new HashMap<>();
map.put("userid",9);
map.put("username","ww");
map.put("userpwd","123");
mapper.MapAddUser(map);
sqlSession.commit();
sqlSession.close();
}
mybatis中的#{}和${}的区别?
前者是占位符 会进行预编译,解析为一个参数占位符‘?’将传入的数据当做一个字符串,当解析成sql语句时,会在变量外侧自动加入引号,能很大程度的防止sql注入
${}方法是拼接符 将传入的数据直接显示生成sql中,一般用在传入数据库对象例如表名
那么什么是sql预编译?
通过Statement对象执行SQL语句时需要先发送给数据库关系系统DBMS,由其进行编译后再执行。每执行一条sql语句都需要先校验sql语句的正确性,再编译成可执行的函数。如果有很多相同的sql语句(但是输入参数不一样),则每次都需要校验编译,在上面消耗的时间花费很多,于是有了预编译。
而预编译PreparedStatement是Statement的子接口,将一些灵活的参数值以占位符的形式代替掉,先会将参数值提取出来 ,将sql语句进行规模化
由于采用Cache机制,则预先编译的语句会放在Cache中,下一次执行相同的sql语句时则可以直接从Cache中取出来。上面说会进行规模化并不会将参数的内容作为sql执行的一部分,而是作为一个字段的属性值来处理,所以就算包含了破坏性的语句例如(1=1)也不会被执行。这也是预编译防止sql注入的原理
需要注意的是,mybatis排序时使用order by动态参数时需要用$
【拓展】模糊查询
方法一:${……}
这种方法上述说了容易导致sql注入,尽量少用
方法二:#{……}
方法三:使用sql内置函数CONCAT
…… like CONCAT(‘%’,#{……},’%’)