MyBatis在配置mapper.xml映射文件中进行与对应的接口进行传递参数处出现了异常:
Exception in thread “main” org.apache.ibatis.exceptions.PersistenceException:
Error querying database. Cause: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named ‘xxx’ in ‘class java.lang.String’
Cause: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named ‘xxx’ in ‘class java.lang.String’
异常翻译:该异常就是说在String类中找不到属性xxx。常见的就是当接口和mapper.xml传递单个参数时用${}取值时;
制造异常:
dao接口中的方法定义:
ArrayList<User> selectByName(String name);
Xxxmapper.xml映射配置文件中的sql:
<select id="selectByName" resultType="user" parameterType="string"> select * from users where name='${name}' </select>
测试类中的调用:
ArrayList<User> users = userDao.selectByName("郭德纲");
解决办法:
将mapper文件中的${name}替换成MyBatis提供的固定获取单参数值方式:${_parameter} 或 ${value}
粗略解释:当传递单个值时若使用${xxx}相当于获取String类中的xxx属性(当传递单个基本数据类型参数时,都会发生这样的异常)
1、 ${}类似于原始JDBC中的Statement,采用的时拼接sql的方式生成,直接将${xxx}对应的内容直接拼接到sql语句中:
<!-- 比如${xxx}对应的内容是 Tom and 1=1 --> <select id="selectByName" resultType="user" parameterType="string"> select * from users where name=${xxx}; </select>
上面标签中的sql就 是:
select * from users where name=Tom and 1=1;
1、很明显不能防止sql注入。
2、如果传递的值是字符串,没有自动添加引号,主要在标签中${xxx}两端自动拼接引号(单双引号)都行:’’${xxx}’’。
2、#{}类似于原始JDBC中的PrepareStatement,采用占位符的方式,生成sql语句,会将#{xxx}对应的内容当做字符串的形式填入对应的占位符位置上。
<!-- 比如${xxx}对应的内容是 Tom and 1=1 --> <select id="selectByName" resultType="user" parameterType="string"> select * from users where name=#{xxx}; </select>
上面标签中的sql就是:
select * from users where name=‘Tom and 1=1’ ;
1、可以在很大程度上防止sql注入。
2、该方式将对应的内容当做字符串,会自动加上引号,对于非字符串数据会利用数据库的自动类型转换,不用我们处理。