Java面试题之MyBatis

发布时间 2023-09-29 21:35:53作者: Vision-H

1.MyBatis 中 #{}和${}的区别是什么

  • #{}是预编译处理, ${}是字符串替换;

  • Mybatis 在处理#{}时, 会将 sql 中的#{}替换为?号, 调用 PreparedStatement 的 set 方法来赋值;

  • Mybatis 在处理${}时, 就是把${}替换成变量的值;

  • 使用#{}可以有效的防止 SQL 注入, 提高系统安全性 。

2.Mybatis 中一级缓存与二级缓存

一级缓存:

  • 一级缓存是MyBatis默认开启的,它指的是在同一个SqlSession中,执行相同的查询语句时,会将查询结果缓存在内存中。
  • 一级缓存的作用范围是SqlSession级别的,也就是说只在当前SqlSession中有效。
  • 当SqlSession进行更新(插入、更新、删除)操作或手动清除缓存时,一级缓存会被清空。

二级缓存:

  • 二级缓存是MyBatis的全局缓存,它可以跨SqlSession使用,适用于多个SqlSession之间共享数据的场景。
  • 默认情况下,二级缓存是关闭的,需要在mybatis-config.xml配置文件中进行配置。
  • 开启二级缓存后,MyBatis会将查询结果序列化并存储在缓存中,下次查询时可以直接从缓存中获取结果。
  • 二级缓存的作用范围是Mapper级别的,也就是同一个Mapper接口下的查询可以共享缓存。
  • 当进行更新操作时(插入、更新、删除),或手动清除缓存时,二级缓存会被清空。

3.MyBatis 如何获取自动生成的(主)键值

在 MyBatis 中获取自动生成的主键值可以通过以下方式进行操作:

  • 在插入操作中使用 useGeneratedKeys 属性和 keyProperty 属性。示例如下:
@Insert("INSERT INTO my_table(column1, column2) VALUES(#{column1}, #{column2})")
@Options(useGeneratedKeys = true, keyProperty = "id")
int insertData(MyModel myModel);

  useGeneratedKeys 设置为 true,表示告诉 MyBatis 使用生成的主键值。而 keyProperty 则指定了对象中用于接收主键值的属性。

  • 在 XML 映射文件中使用 <insert> 元素,结合 <selectKey> 元素。示例如下:
<insert id="insertData" parameterType="com.example.MyModel">
    INSERT INTO my_table(column1, column2)
    VALUES(#{column1}, #{column2})
    <selectKey keyProperty="id" resultType="java.lang.Long" order="AFTER">
        SELECT LAST_INSERT_ID()
    </selectKey>
</insert>

  <selectKey> 元素用于执行查询语句获取生成的主键值,并将其赋给 id 属性。

4.简述 Mybatis 的动态 SQL, 列出常用的标签及作用

MyBatis的动态SQL是一种在XML配置文件中根据条件动态生成SQL语句的技术。通过使用动态SQL,可以根据不同的查询条件来构建不同的SQL语句,以实现更加灵活和可扩展的数据库操作。

   1.<if>标签:根据指定的条件判断是否包含某段SQL语句。示例:

<select id="getUserList" resultType="User">
  SELECT * FROM user
  WHERE 1=1
    <if test="name != null">
      AND name = #{name}
    </if>
    <if test="age != null">
      AND age = #{age}
    </if>
</select>

   2.<choose><when><otherwise> 标签:用于实现类似于 Java 中的 switch-case 的功能,根据不同的条件选择不同的分支。示例:

<select id="getUserList" resultType="User">
  SELECT * FROM user
  WHERE 1=1
  <choose>
    <when test="name != null">
      AND name = #{name}
    </when>
    <when test="age != null">
      AND age = #{age}
    </when>
    <otherwise>
      AND status = 'active'
    </otherwise>
  </choose>
</select>

   3.<trim> 标签:用于处理SQL语句中的前缀、后缀或者中间部分的空白字符。示例:

<select id="getUserList" resultType="User">
  SELECT *
  FROM user
  <trim prefix="WHERE" prefixOverrides="AND | OR">
    <if test="name != null">
      AND name = #{name}
    </if>
    <if test="age != null">
      AND age = #{age}
    </if>
  </trim>
</select>

   4.<foreach> 标签:用于遍历集合或数组,并将每个元素作为SQL语句中的一部分进行处理。示例:

<select id="getUserList" resultType="User">
  SELECT *
  FROM user
  WHERE id IN
  <foreach item="id" collection="ids" open="(" separator="," close=")">
    #{id}
  </foreach>
</select>

   5.<set> 标签:用于根据不同的条件动态生成更新语句中的 SET 子句。示例:

<update id="updateUser" parameterType="User">
  UPDATE user
  <set>
    <if test="name != null">
      name = #{name},
    </if>
    <if test="age != null">
      age = #{age},
    </if>
  </set>
  WHERE id = #{id}
</update>