整理一些自己糊涂的知识点,多为摘抄整合的,如有侵权,请联系我立刻删除!
一、#{}和${}
#{}表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换。#{}可以有效防止sql注入。 #{}可以接收简单类型值或pojo属性值。 如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。
${}表示拼接sql串,通过${}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换, ${}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,${}括号中只能是value。
1.什么是sql注入?有什么危害?
比如下面的sql语句:
SQL = "SELECT * FROM users WHERE name = '" + userName + "' and pw = '"+ passWord +"';"
如果登录时恶意填入
userName = "1' OR '1'='1";
passWord = "1' OR '1'='1";
sql语句就变成了
SQL = "SELECT * FROM users WHERE name = '1' OR '1'='1' and pw = '1' OR '1'='1';"
因为sql语句where条件恒为真,sql就相当于执行
SQL = "SELECT * FROM users;"
导致无效的账户名密码也能登陆系统。这就是sql注入,以及带来的危害。使用PreparedStatement可以预防sql注入。
2.为什么PreparedStatement可以防止sql注入?
PreparedStatement执行SQL语句,采用的是预编译的方式。预编译的SQL语句不是有具体数值的语句,而是用(?)来代替具体数据,然后在执行的时候再调用setXX()方法把具体的数据传入。在程序运行时第一次操作数据库之前,SQL语句已经被数据库分析,编译和优化,对应的执行计划也会缓存下来并允许数据库已参数化的形式进行查询,当运行时动态地把参数传给PreprareStatement时,即使参数里有敏感字符如 or '1=1'也数据库会作为一个参数一个字段的属性值来处理而不会作为一个SQL指令,如此,就起到了预防SQL注入的作用了!
二、where标签
UserMapper.xml如下
<!-- 根据条件查询用户 -->
<select id="queryUserByWhere" parameterType="user" resultType="user">
SELECT id, username, birthday, sex, address FROM `user`
<!-- where标签可以自动添加where,同时处理sql语句中第一个and关键字 -->
<where>
<if test="sex != null">
AND sex = #{sex}
</if>
<if test="username != null and username != ''">
AND username LIKE
'%${username}%'
</if>
</where>
</select>
<where>标签当包裹的<if>标签有返回的时候自动添加where,并且删除sql语句中的第一个and关键字,比如上面查询条件两个if都没有进入,则不添加where。结果就执行如下
<!-- 根据条件查询用户 -->
<select id="queryUserByWhere" parameterType="user" resultType="user">
SELECT id, username, birthday, sex, address FROM `user`
</select>
如果if条件进入了,去除第一个and,添加where,即执行如下
<!-- 根据条件查询用户 -->
<select id="queryUserByWhere" parameterType="user" resultType="user">
SELECT id, username, birthday, sex, address FROM `user`
<!-- where标签可以自动添加where,同时处理sql语句中第一个and关键字 -->
where sex = #{sex} AND username LIKE '%${username}%'
</select>
三、foreach标签
向sql传递数组或List,mybatis使用foreach解析,如:根据多个id查询用户信息
查询sql:
SELECT * FROM user WHERE id IN (1,10,24)
如下在pojo中定义list属性ids存储多个用户id:
public class QueryVo{
private User user;
private List<Integer> ids;
}
UserMapper.xml添加sql,如下
<!-- 根据ids查询用户 -->
<select id="queryUserByIds" parameterType="queryVo" resultType="user">
SELECT * FROM `user`
<where>
<!-- foreach标签,进行遍历 -->
<!-- collection:遍历的集合,这里是QueryVo的ids属性 -->
<!-- item:遍历的项目,可以随便写,,但是和后面的#{}里面要一致 -->
<!-- open:在前面添加的sql片段 -->
<!-- close:在结尾处添加的sql片段 -->
<!-- separator:指定遍历的元素之间使用的分隔符 -->
<foreach collection="ids" item="item" open="id IN (" close=")"
separator=",">
#{item}
</foreach>
</where>
</select>
四、关联查询
一对一查询、一对多查询、多对多查询;
<association> 和 <collection>的用法;