mybatis占位符的讲解
在mybatis中,占位符有两个,一个是#,一个是$,这两个有什么区别,我们分别来讲解一下
1. 占位符#{}
语法:#{字符}
#占位符告诉mybatis使用实际的参数值代替。并,#{…}代替sql语句的"?"。这样做更安全,更迅速,通常也是首选做法
mapper文件中
<select id="selectStudentById" parameterType="int" resultType="com.lu.entity.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, 1001); //传递参数
ResultSet rs = ps.executeQuery(); //执行sql语句
#{}占位符的特点:
- 使用
PrepareStatement对象执行sql语句 - 使用
PrepareStatement对象,能避免sql注入,sql语句执行更安全 - #{}常常作为列值使用的,位于等号的右侧,#{}位置的值和数据类型有关的
2. 占位符${}
语法:${字符}
mybatis执行${}占位符的sql语句
<select id="selectStudentById" parameterType="int" resultType="com.lu.entity.Student">
select id, name, email, age from student where id = ${studentId}
</select>
表 示 字 符 串 连 接 , 把 ‘ s q l ‘ 语 句 的 其 他 内 容 和 {}表示字符串连接,把`sql`语句的其他内容和 表示字符串连接,把‘sql‘语句的其他内容和{}内容使用字符串(+) 连接的方式连在一起
转为mybatis的执行是:
String sql = "select id, name, email, age from student where id =" + "1001";
Statement stmt = conn.createStatement(sql);
ResultSet rs = stmt.executeQuery();
${}的特点
- 使用Statement对象,执行
sql语句,效率低 - ${}占位符的值,使用的字符串连接方式,有
sql注入的风险。有代码安全的问题 - ${}数据是原样使用的,不会区分数据类型
- 常 用 作 表 名 或 者 列 明 , 再 能 保 证 数 据 安 全 的 情 况 下 使 用 {}常用作表名或者列明,再能保证数据安全的情况下使用 常用作表名或者列明,再能保证数据安全的情况下使用{}
我们来实现一个例子,首先在dao接口中写方法
List<Student> queryStudent(@Param("studentname") String name);
在mapper文件中
<select id="queryStudent" resultType="com.lu.entity.Student">
select * from student where name = ${studentname}
</select>
在测试类中
@Test
public void testQueryStudent() {
SqlSession session = MyBatisUtil.getSqlSession();
StudentDao dao = session.getMapper(StudentDao.class);
List<Student> students = dao.queryStudent("张三");
students.forEach(student -> System.out.println(student));
session.close();
}
我们来执行一下

报了一个错,代码把张三当成一个列了,那么我们怎么修改呢
List<Student> students = dao.queryStudent("'张三'");
我们需要在传值的时候在值的两边加上单引号 ''
再重新执行一下,发现可以查询成功了

还有一点我们需要注意的,就是在dao接口中定义方法的时候,我们必须用@Param来指定名称,不然同样会报错。
${}最不能解决的问题,就是sql注入的问题,关于sql注入,可以看这一篇文章
3. #{}和${}组合使用
有时候我们单独的使用#{}或者${}都不能很好的解决问题,比如下面这个例子
我们要从指定的数据中查询名字为XXX的数据,并且按照姓名进行降序排序
首先在dao接口中定义方法
List<Student> queryStudentOrderByColumn(@Param("myname") String name, @Param("colName") String colName, @Param("tableName") String tableName);
在mapper文件中
<select id="queryStudentOrderByColumn" resultType="com.lu.entity.Student">
select * from ${tableName} where name = #{myname} order by ${colName} desc
</select>
在测试类中
@Test
public void testQueryStudentOrderByColName() {
SqlSession session = MyBatisUtil.getSqlSession();
StudentDao dao = session.getMapper(StudentDao.class);
List<Student> students = dao.queryStudentOrderByColumn("张三", "id", "student");
students.forEach(student -> System.out.println(student));
session.close();
}
控制台输出:

现在我们已经实现了#{}和${}的组合使用
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)