文章目录
- 1、resultType和resultMap
- 2、MyBatis获取参数值的两种方式
-
- 2.1、两种方式的区别
- [2.2、{}的SQL注入问题](#2.2、{}的SQL注入问题)
- 3、动态标签
-
- [3.1. if & where](#3.1. if & where)
- [3.2. trim](#3.2. trim)
- [3.3. choose、when、otherwise](#3.3. choose、when、otherwise)
- [3.4. foreach](#3.4. foreach)
- [3.5. SQL片段](#3.5. SQL片段)
1、resultType和resultMap
- resultType
自动映射,用于属性名和表中字段名一致的情况。
java
<select id="getUserList" resultType="com.atguigu.mybatis.bean.User">
select * from t_user
</select>
也可以使用别名的方式实现
java
<select id="getUserList" resultType="com.atguigu.mybatis.bean.User">
select user_name AS username
user_id AS id
from t_user
</select>
- resultMap
自定义映射,用于一对多
或多对一
或字段名和属性名
不一致的情况。
java
<!--
resultMap:设置自定义映射
属性:
id:表示自定义映射的唯一标识
type:查询的数据要映射的实体类的类型
子标签:
id:设置主键的映射关系
result:设置普通字段的映射关系
association:设置多对一的映射关系
collection:设置一对多的映射关系
属性:
property:设置映射关系中实体类中的属性名
column:设置映射关系中表中的字段名
-->
<resultMap id="userMap" type="User">
<id property="id" column="id"></id>
<result property="userName" column="user_name"></result>
<result property="password" column="password"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
</resultMap>
<select id="testMohu" resultMap="userMap">
select id,user_name,password,age,sex from t_user
</select>
2、MyBatis获取参数值的两种方式
MyBatis获取参数值的两种方式:${}
和#{}
2.1、两种方式的区别
- ${}的本质就是
字符串拼接
;#{}的本质就是占位符赋值
,是指 MyBatis 在处理 #{} 时,就是把 #{} 替换成了 "?",使用 PreparedStatement 的 set 方法来赋值 - ${}使用字符串拼接的方式拼接sql,若为字符串类型或日期类型的字段进行赋值时,需要手动加单引号;
但是#{}使用占位符赋值的方式拼接sql,此时为字符串类型或日期类型的字段进行赋值时,可以自动添加单引号。
2.2、${}的SQL注入问题
例如现在有一个登陆程序,需要输入正确的账户和密码才能登录,当使用了 SQL 注入就可以在不知道密码的情况下进行登录。
1.SQL查询语句如下:
bash
<select id="login" resultType="com.example.demo.entity.Userinfo">
select * from userinfo where username = '${username}' and password = '${password}'
</select>
2.接口如下:
java
/**
* 登录逻辑
* @param username
* @param password
* @return
*/
Userinfo login(@Param("username") String username,
@Param("password") String password);
3.测试方法为:
java
@Test
void login() {
String username = "admin";
String password = "' or 1 = '1";
Userinfo userinfo = userMapper.login(username, password);
System.out.println("登录状态:" + (userinfo == null ? "失败" : "成功"));
}
4.结果为:
5.原因为:
通过运行日志,可以看到此时的SQL语句为
sql
select * from userinfo where username = 'admin' and password = '' or 1 = '1';
可以看出username = 'admin' and password = ''
的结果为false,'or 1 = '1
为true,所以将表中所有内容都查出来了。本来想要的是password='传进来的值'
,但是 ${} 直接拼接,导致 ' or 1 = 1' 左边的 ' 和 ' ${password} ' 左边的 ' 结合, 右边也结合,直接多出了一个or。
3、动态标签
3.1. if & where
bash
<select id="getEmpList" resultType="Emp">
select * from t_emp
<where>
<if test="name != '' and name != null">
name = #{name}
</if>
<if test="age != '' and age != null">
and age = #{age}
</if>
</where>
</select>
- if 标签可通过
test
属性(即传递过来的数据)的表达式进行判断,若表达式的结果为true,则标签中的内容会执行;反之标签中的内容不会执行。 - 若where标签中的if条件都不满足,则where标签没有任何功能,即不会添加where关键字
- 若where标签中的if条件满足,则where标签会自动添加where关键字,并将条件最前方多余的and/or去掉
3.2. trim
bash
<select id="getEmpByCondition" resultType="Emp">
select * from t_emp
<trim prefix="where" suffixOverrides="and|or">
<if test="empName != null and empName !=''">
emp_name = #{empName} and
</if>
<if test="age != null and age !=''">
age = #{age} and
</if>
<if test="sex != null and sex !=''">
sex = #{sex} or
</if>
<if test="email != null and email !=''">
email = #{email}
</if>
</trim>
</select>
- trim用于去掉或添加标签中的内容
- 常用属性
- prefix:在trim标签中的内容的
前面添加某些内容
- suffix:在trim标签中的内容的
后面添加某些内容
- prefixOverrides:在trim标签中的内容的
前面去掉某些内容
- suffixOverrides:在trim标签中的内容的
后面去掉某些内容
- prefix:在trim标签中的内容的
3.3. choose、when、otherwise
choose...when...otherwise
相当于if...else if..else
- when至少要有一个,otherwise至多只有一个
bash
<select id="getEmpByChoose" resultType="Emp">
select * from t_emp
<where>
<choose>
<when test="empName != null and empName != ''">
emp_name = #{empName}
</when>
<when test="age != null and age != ''">
age = #{age}
</when>
<otherwise>
did = 1
</otherwise>
</choose>
</where>
</select>
3.4. foreach
- 属性
- collection:设置要循环的数组或集合
- item:表示集合或数组中的每一个数据
- separator:设置循环体之间的分隔符,如","。分隔符前后默认有一个空格
- open:设置foreach标签中的内容的开始符
- close:设置foreach标签中的内容的结束符
bash
<delete id="deleteMoreByArray">
delete from t_emp where eid in
<foreach collection="eids" item="eid" separator="," open="(" close=")">
#{eid}
</foreach>
</delete>
3.5. SQL片段
sql片段,可以记录一段公共sql片段,在使用的地方通过include
标签进行引入
bash
<sql id="empColumns">
eid,ename,age,sex,did
</sql>
select <include refid="empColumns"></include> from t_emp