在学习 **mybatis** 框架的过程中,我们都知道动态 **sql** 是 **mybatis** 的主要特性之一,在 **mapper** 中定义的参数传到 **xml** 中之后,在查询之前 **mybatis** 会对其进行动态解析。**mybatis** 为我们提供了两种支持动态 **sql** 的语法:`#{}` 以及 `${}`。那么它们之间的区别是什么呢?
一、相同点
用于指定传入参数的类型
二、不同点
2.1、使用#{}字符:表示一个占位符号 相当于 ?
它代表占位符,相当于原来 **jdbc** 部分所学的 `?` ,都是用于执行语句时替换实际的数据。具体的数据是由 `#{}` 里面的内容决定的。通过 `#{}` 可以实现 **preparedStatement** 向占位符中设置值,自动进行 **java** 类型和 **jdbc** 类型转换,`#{}` 可以有效防止 **sql** 注入。`#{}` 可以接收简单类型值(为值传递)或 **pojo** 属性值(通过引用传递)。 如果 **parameterType** 传入单个简单类型值,`#{}` 括号中可以是 **value** 或其它名称。
2.2、使用${} --表示拼接 sql 串
代表字符串拼接,通过 `${}` 可以将 **parameterType** 传入的内容拼接在 **sql** 中且不进行 **jdbc** 类型转换,`${}` 可以接收简单类型值或 **pojo** 属性值,如果 **parameterType** 传入单个简单类型值,`${}`括号中只能是 **value**。
`#{}` 表示一个占位符即 `?` ,可以有效防止 **sql** 注入。在使用时不需要关心参数值的类型,**mybatis** 会自动进行 **java** 类型和 **jdbc** 类型的转换。
`#{}` 可以接收简单类型值或 **pojo** 属性值,如果传入简单类型值,`#{}` 括号中可以是任意名称。
<!-- 根据名称模糊查询用户信息 --><select id="findUserById" parameterType="String" resultType="user">select*from user where username like CONCAT(CONCAT('%', #{name}),'%')</select>
`${}` 可以将 **parameterType** 传入的内容拼接在 **sql** 中且不进行 **jdbc** 类型转换。
`${}`可以接收简单类型值或 **pojo** 属性值,如果传入简单类型值,`${}` 括号中名称只能是 **value**。
<!-- 根据名称模糊查询用户信息 --><select id="selectUserByName" parameterType="string" resultType="user">select*from user where username like'%${value}%'</select>
对于 **order by** 排序,使用 `#{}`将无法实现功能,所以必须使用`${}`, 应该写成如下形式:
ORDERBY ${columnName}
另外,对于 **mybatis** 逆向工程生成的代码中,进行模糊查询调用 **andXxxLike()** 方法时,需要手动加 `%`,如下:
CustomerExample customerExample = new CustomerExample();customerExample.or().andNameLike("%"+name+"%");
欢迎大家相互交流学习,如有不对之处,希望不吝赐教。
完结!