掌握#和$
#:占位符,告诉 mybatis 使用实际的参数值代替。并使用 PrepareStatement 对象执行 sql 语句, #{…}代替
sql 语句的“?”。这样做更安全,更迅速,通常也是首选做法,
mapper 文件
<select id="selectById" resultType="com.bjpowernode.domain.Student">
select id,name,email,age from student where id=#{studentId}
</select>
转为 MyBatis 的执行是:
String sql=” select id,name,email,age from student where id=?”;
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1,1005);
解释:
where id=? 就是 where id=#{studentId}
ps.setInt(1,1005) , 1005 会替换掉 #{studentId}
$ 字符串替换,告诉 mybatis 使用$包含的“字符串”替换所在位置。使用 Statement 把 sql 语句和${}的
内容连接起来。主要用在替换表名,列名,不同列排序等操作。
select id,name,email,age from student where id=${Id}
相当于:String sql = "select id,name,email,age from student where id=" + "1002";
使用的Stratement对象执行sql,效率比Preparement低,而且会出现安全隐患
如:
@Test public void selectUse$() { /* * 使用mybatis的动态代理机制,使用SqlSession.getMapper(dao接口) * getMapper能获取dao接口对应的实现类对象 * * */ SqlSession sqlSession = MyBatisUtils.getSqlSession(); StudentDao dao = sqlSession.getMapper(StudentDao.class); // List<Student> student = dao.selectUse$("'李四'"); List<Student> student = dao.selectUse$("'李四;drop table student'"); //出现了sql注入 System.out.println(student); sqlSession.close(); }
总结:(面试高频)
#和$区别:
1.#使用 ?在sql语句中做占位的, 使用PrepareStatement执行sql,效率高
2.#能够避免sql注入,更安全
3.$不使用占位符,是字符串连接方式,使用Statement对象执行sql,效率低
4.$有sql注入的风险,缺乏安全性
5.$ 可以替换表名或者列名