MyBatis中常见的面试题
sql语句使用 #{ } 和 ${ } 的区别
- #{}:预编译处理
- ${}:字符直接替换
预编译处理:MyBatis 在处理#{}时,会将 SQL 中的 #{} 替换为?号,使用 PreparedStatement的 set 方法来赋值。
直接替换:MyBatis 在处理 ${} 时,就是把 ${} 替换成变量的值。
参数直接替换,可能会带来越权查询和数据操作等问题,说直白点就是有个人不知道你家密码但是进入你家了,会有安全问题,不如发生SQL注入
select * from userinfo where username =#{username}
select * from userinfo where username =${username}
select * from userinfo where username ='${username}'
UserInfo username = userMapper.getUsername("admin");
使用单元测试,传数据为username= admin
1.查出来username = admin 的用户信息
2.查出来username = null
因为sql语句在查询时,必须要给字符串加一个’ '(单引号),#{} 就会自动添加,第3句就可以查询到,但是太麻烦
select * from userinfo order by id ${order}
List<UserInfo> userInfo = userMapper.getAllbyOrder("asc");
asc,desc本来就是MySQL的关键字,使用#{}会出错
但是传递数字时,${} 可以使用
select * from userinfo where id=#{id}
select * from userinfo where id=${id}
SQL注入问题
select * from userinfo where username =${username} and password =${password}
使用上述代码本来是任何都查询不到的
String username = "'李四'";
String password= "'' or 1='1'";
但是传参时,使用上述代码就可以将数据表的信息出来,关键就在于脚本 ' or 1='1
’
resultType和resultMpe的区别
对于 查询标签来说至少需要两个属性:
- id 属性:用于标识实现接口中的那个方法
- 结果映射属性:结果映射有两种实现标签: resultType 和 resultMap
绝大数查询场景可以使用 resultType 进行返回
<select id="getId" resultType="com.example.demo.model.UserInfo">
select * from userinfo where id=#{id}
</select>
resultMap用来解决参数名不一致的问题
代码附上
<resultMap id="BaseMap" type="com.example.demo.model.UserInfo">
<id column = "id" property="id"></id>
<result column = "username" property="name"></result>
</resultMap>
<select id="getAll" resultMap="BaseMap">
select * from userinfo
</select>
欢迎评论和提问!!