Mybatis

文章目录

  • 1、resultType和resultMap
  • 2、MyBatis获取参数值的两种方式
    • 2.1、两种方式的区别
    • 2.2、${}的SQL注入问题
  • 3、动态标签
    • 3.1. if & where
    • 3.2. trim
    • 3.3. choose、when、otherwise
    • 3.4. foreach
    • 3.5. SQL片段

1、resultType和resultMap

  1. resultType

自动映射,用于属性名和表中字段名一致的情况。

<select id="getUserList" resultType="com.atguigu.mybatis.bean.User">
   select * from t_user
</select>

也可以使用别名的方式实现

<select id="getUserList" resultType="com.atguigu.mybatis.bean.User">
   select user_name AS username
     user_id AS id
   from t_user 
</select>
  1. resultMap
    自定义映射,用于一对多多对一字段名和属性名不一致的情况。
<!--
  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、两种方式的区别

  1. ${}的本质就是字符串拼接;#{}的本质就是占位符赋值,是指 MyBatis 在处理 #{} 时,就是把 #{} 替换成了 “?”,使用 PreparedStatement 的 set 方法来赋值
  2. ${}使用字符串拼接的方式拼接sql,若为字符串类型或日期类型的字段进行赋值时,需要手动加单引号;
    但是#{}使用占位符赋值的方式拼接sql,此时为字符串类型或日期类型的字段进行赋值时,可以自动添加单引号。

2.2、${}的SQL注入问题

例如现在有一个登陆程序,需要输入正确的账户和密码才能登录,当使用了 SQL 注入就可以在不知道密码的情况下进行登录。
1.SQL查询语句如下:

    <select id="login" resultType="com.example.demo.entity.Userinfo">
        select * from userinfo where username = '${username}' and password = '${password}'
    </select>

2.接口如下:

/**
     * 登录逻辑
     * @param username
     * @param password
     * @return
     */
    Userinfo login(@Param("username") String username,
                   @Param("password") String password);

3.测试方法为:

    @Test
    void login() {
        String username = "admin";
        String password = "' or 1 = '1";
        Userinfo userinfo = userMapper.login(username, password);
        System.out.println("登录状态:" + (userinfo == null ? "失败" : "成功"));
    }

4.结果为:
Mybatis_第1张图片
5.原因为:
通过运行日志,可以看到此时的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

<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

<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用于去掉或添加标签中的内容
  • 常用属性
    1. prefix:在trim标签中的内容的前面添加某些内容
    2. suffix:在trim标签中的内容的后面添加某些内容
    3. prefixOverrides:在trim标签中的内容的前面去掉某些内容
    4. suffixOverrides:在trim标签中的内容的后面去掉某些内容

3.3. choose、when、otherwise

  • choose...when...otherwise相当于if...else if..else
  • when至少要有一个,otherwise至多只有一个
<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

  • 属性
    1. collection:设置要循环的数组或集合
    2. item:表示集合或数组中的每一个数据
    3. separator:设置循环体之间的分隔符,如“,”。分隔符前后默认有一个空格
    4. open:设置foreach标签中的内容的开始符
    5. close:设置foreach标签中的内容的结束符
<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标签进行引入

<sql id="empColumns">
   eid,ename,age,sex,did
</sql>

select <include refid="empColumns"></include> from t_emp

1.新人一看就懂 #{} 和 $ {} 的区别
2.# 和 $ 的区别

你可能感兴趣的:(Spring,mybatis,动态标签,foreach,resultType,resultMap)