Mybatis 数据库框架 mapper文件中 # 与 $ 符号的区别

动态 sql 是 mybatis 的主要特性之一,在 mapper 中定义的参数传到 xml 中之后,在查询之前 mybatis 会对其进行动态解析。mybatis 提供了两种支持动态 sql 的语法:#{} 以及 ${} 。

1、#{} : 根据参数的类型进行合适的处理

比如传入String类型,会为参数加上双引号,如果传入Integer类型数据,则不会为参数加上双引号。#{} 传参在进行SQL预编译时,会把参数部分用一个占位符 ? 代替,这样可以防止 SQL注入。

2、${} : 将参数取出不做任何处理

直接放入语句中,就是简单的字符串替换,并且该参数会参加SQL的预编译,需要手动过滤参数防止 SQL注入。

3、因此 mybatis 中优先使用 #{}

当需要动态传入 表名或列名时,再考虑使用 ${} ,比较特殊,他的应用场景是需要动态传入表名或列名时使用,MyBatis排序时使用orderby动态参数时需要注意,用{} 比较特殊, 他的应用场景是 需要动态传入 表名或列名时使用,MyBatis排序时使用order by 动态参数时需要注意,用比较特殊,他的应用场景是需要动态传入表名或列名时使用,MyBatis排序时使用orderby动态参数时需要注意,用而不是 # 。

例如

1、#{} 对传入的参数视为字符串

mapper文件中的语句为

<select id="findUserByUserName" resultType="User" >
    select * from user where userName = ${userName}
</insert>

例如传入的参数是 String userName = "root" ,mybatis处理后的则是

select * from user where userName = 'root'

2、#{} 对传入的参数视为数字类型

mapper文件中的语句为

<select id="findUserByUserId" resultType="User" >
    select * from user where userId = ${userId}
</insert>

例如传入的参数是 int userId = 9527; ,mybatis处理后的则是

select * from user where userId = 9527 

3、${} 不会将传入的值进行预编译

mapper文件中的语句为

<insert id="InsertColumnsInfo">
        ${insertSQL}
</insert>

例如传入的参数是一条SQl语句,
INSERT INTO columns_Info(tableName,columnName,columnType,columnLength,annotation) VALUE(‘z2‘,‘t2‘,‘VARCHAR‘,255,‘annotation‘);
mybatis处理后不做任何改变,则是

INSERT INTO columns_Info(tableName,columnName,columnType,columnLength,annotation) VALUE('z2','t2','VARCHAR',255,'annotation');

总结

${} 可以在java代码中预先拼接复杂的SQL语句直接传入
#{} 优势在于它能很大程度防止sql注入,而${}不行

比如:用户进行一个登录操作,后台sql验证式样的:

<select id="userLogin" resultType="User" >
    select * from user where user_name=#{name} and password = #{pwd}
</select>

如果前台传来的用户名是“rookie”,密码是 “1 or 2”,用 #{} 的方式就不会出现sql注入.
换成用 ${} 方式,sql语句就变成了

select * from user where user_name=rookie and password = 1 or 2

这样的话就形成了sql注入。

Mybatis 数据库框架 mapper文件中 # 与 $ 符号的区别

上一篇:轻量级ORM框架——第一篇:Dapper快速学习


下一篇:关于MyBatis的@Mapper和@MapperScan注解的一点思考