Mybatis映射文件Mapper.xml中#和$的区别

关于Mapper.xml映射语句中什么时候用"#"什么时候用"$",已经有很多人做过总结,我最近在写项目时仍然遇到了一点问题,所以在这里结合项目文档和案例,再做一下总结,也作为个人的笔记,在这里再总结下。

一、先看一下在mybatis api中关于"#"和"$"的描述

1、"#"

图 1来自于mybatis api “Mapper XML文件”章节,   简单来说"#"在编译时使用"?"占位符标记,可以有效防止参数注入,相当于我们使用JDBC操作时的PreparedStatement。

Mybatis映射文件Mapper.xml中#和$的区别_第1张图片                                                                                                 图1

2、"$" 

 图2同样来自于mybatis api “Mapper XML文件”章节,意思是直接把参数拼接到SQL中执行相当于JDBC操作时的Statement

                                                                                          图2

二、结合案例具体说明"#"和"$" 的区别。

1、参数作为非SQL关键字传递

 
      insert into users values(default, ${username}, ${password}, ${photo});
 

该语句执行报错,通过日志分析,

[19:32:41.422] [DEBUG] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:139) ==>  Preparing: insert into users values(default, test, 123456, c9ae464f-348d-491d-a162-a9624c99f73b); 
[19:32:41.479] [DEBUG] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:139) ==> Parameters: 

Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'test' in 'field list'
; bad SQL grammar []; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'test' in 'field list'] with root cause

从这里可以看到,这里直接把获取到的参数拼接到了SQL中,数据库把参数当成了列名,数据库字段设置的都是varchar类型,需要把列值加上"",方可执行成功,如下:


        insert into users values(default, "${username}", "${password}", "${photo}");

日志如下:

[19:42:30.616] [DEBUG] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:139) ==>  Preparing: insert into users values(default, "test", "123456", "85ec0040-46dc-4a92-b995-7ed84ece2f28"); 
[19:42:30.698] [DEBUG] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:139) ==> Parameters: 
[19:42:30.755] [DEBUG] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:139) <==    Updates: 1

或者把"$"改成"#"


        insert into users values(default, #{username}, #{password}, #{photo});
 

2、参数作为关键字传递,比如查询条件全是由参数拼接的,只是用一条SQL,有时要按name列查,有时要按age列查

SQL1:select * from users where username = "test";

SQL2:select * from users where userage like "%2";

因为列名和关系条件是关键字,是用"$",列值是非关键字,使用"#"。

三、总结

1、关键字作为参数,使用"$",两边不加""。

2、非关键字作为参数,使用"#"防注入。

其他情况优先使用"#"

你可能感兴趣的:(java,mybatis,mysql)