sql语句中的 #{} 和 ${} 的区别
#{} | 表示占位符?(是一个预编译的占位符作用),可以防止sql注入,会进行类型自动转换 | 一般推荐使用#{} |
${} | 表示字符串拼接,不能防止sql注入,不安全,并且也不会进行类型自动转换 | 当动态的排序或表名时,只能使用 ${} |
<select id="方法名" parameterType="参数类型" resultType="返回类型">
select * from 表名 where id=#{id}
</select>
什么时候可以使用 ${} ?
当动态的传递 表名 或 字段名称 时(或者 动态的排序 order by),可以使用 ${value}。
<!--需求: 查询所有字段信息,并根据指定的字段来排序(desc是倒序)-->
<select id="方法名" parameterType="参数的类型" resultType="返回值的类型">
select * from 表名 order by ${value} desc;
</select>
<select id="方法名" parameterType="参数的类型" resultType="返回值的类型">
select * from ${表名};
</select>
<!--1. select * from 表名 order by #{id} desc; //会报错 -->
<!--2. 当动态的传递 表名(from表名) 或 字段名称(order by字段)时,只能用${value} -->
配置mybatis-config.xml的时候,可以使用${}来配置
<!-- 配置mybatis-config.xml文件 -->
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--加载外部属性-->
<properties resource="jdbc.properties"/>
<!--运行环境可以配置多个, default指定默认使用哪个-->
<environments default="development">
<!--配置环境, id是这个环境的唯一标识-->
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
</configuration>
总结
1.#{}是占位符,会对SQL进行预编译,相当于?,可以防止SQL注入;${}是直接字符串String替换,有SQL注入的风险,不安全。
(#{}:底层实现依靠PrepareStatement,预编译的时候会将SQL中的#{}替换为?问号,调用PrepareStatement的set方法来赋值的时候都会加上2个单引号)
2.#{}可以对数据类型进行自动转换; ${} 将所有数据当做字符串String来处理。
3.一般做参数传递,都会使用#{};order by字段,from 表名,只能用${}。
推荐方式:
两者都可以使用的时候优先使用#{};
order by字段,from表名,只能用${}。