1. 什么是 Mybatis?

  • Mybatis 是 一 个 半 ORM( 对 象 关 系 映 射 )框 架 ,它 内 部 封 装 了 JDBC,开 发 时
    只 需 要 关 注 SQL 语 句 本 身 , 不 需 要 花 费 精 力 去 处 理 加 载 驱 动 、 创 建 连 接 、 创 建
    statement 等 繁 杂 的 过 程 。程 序 员 直 接 编 写 原 生 态 sql,可 以 严 格 控 制 sql 执 行 性
    能 , 灵 活 度 高 。
  • MyBatis 可 以 使 用 XML 或 注 解 来 配 置 和 映 射 原 生 信 息 , 将 POJO 映 射 成 数
    据 库 中 的 记 录 , 避 免 了 几 乎 所 有 的 JDBC 代 码 和 手 动 设 置 参 数 以 及 获 取 结 果 集 。
  • 通 过 xml 文 件 或 注 解 的 方 式 将 要 执 行 的 各 种 statement 配 置 起 来 , 并 通 过
    java 对 象 和 statement 中 sql 的 动 态 参 数 进 行 映 射 生 成 最 终 执 行 的 sql 语 句 ,最
    后 由 mybatis 框 架 执 行 sql 并 将 结 果 映 射 为 java 对 象 并 返 回 。 ( 从 执 行 sql 到 返
    回 result 的 过 程 ) 。

2. Mybaits 的优点?

  • 基 于 SQL 语 句 编 程 ,相 当 灵 活 ,不 会 对 应 用 程 序 或 者 数 据 库 的 现 有 设 计 造 成 任
    何 影 响 ,SQL 写 在 XML 里 ,解 除 sql 与 程 序 代 码 的 耦 合 ,便 于 统 一 管 理 ;提 供 XML
    标 签 , 支 持 编 写 动 态 SQL 语 句 , 并 可 重 用 。
  • 与 JDBC 相 比 ,减 少 了 50%以 上 的 代 码 量 ,消 除 了 JDBC 大 量 冗 余 的 代 码 ,不
    需 要 手 动 开 关 连 接 。
  • 很 好 的 与 各 种 数 据 库 兼 容( 因 为 MyBatis 使 用 JDBC 来 连 接 数 据 库 ,所 以 只 要
    JDBC 支 持 的 数 据 库 MyBatis 都 支 持 ) 。
  • 能 够 与 Spring 很 好 的 集 成 ;
  • 提 供 映 射 标 签 , 支 持 对 象 与 数 据 库 的 ORM 字 段 关 系 映 射 ; 提 供 对 象 关 系 映 射
    标 签 , 支 持 对 象 关 系 组 件 维 护 。

3. MyBatis 框架的缺点?

  • SQL 语 句 的 编 写 工 作 量 较 大 , 尤 其 当 字 段 多 、 关 联 表 多 时 , 对 开 发 人 员 编 写
    SQL 语 句 的 功 底 有 一 定 要 求 。
  • SQL 语 句 依 赖 于 数 据 库 , 导 致 数 据 库 移 植 性 差 , 不 能 随 意 更 换 数 据 库 。

4. MyBatis 框架适用场合:

5. #{}和${}的区别是什么?

  • #{} 会对传入的参数进行预编译,将参数值放入一个占位符中,然后使用 JDBC 的 PreparedStatement 执行 SQL 语句,这样可以防止 SQL 注入攻击。
  • ${} 不会对传入的参数进行预编译,它会直接将传入的参数值拼接到 SQL 语句中,可能会导致 SQL 注入攻击。
<!-- 使用 #{} -->
<select id="getUserById" resultType="User">
  SELECT * FROM users WHERE id = #{id}
</select>
<!-- 使用 ${} -->
<select id="getUserByName" resultType="User">
  SELECT * FROM users WHERE name = '${name}'
</select>

6. 当实体类中的属性名和表中的字段名不一样 ,怎么办 ?

  • 使用注解
public class User {
    @Column(name = "user_id")
    private Integer id;
    private String username;
    private String password;
    // ...省略其他属性和方法
}
  • 通 过 来 映 射 字 段 名 和 实 体 类 属 性 名 的 一 一 对 应 的 关 系 。
<resultMap id="userResultMap" type="User">
    <id column="user_id" property="id"/>
    <result column="username" property="username"/>
    <result column="password" property="password"/>
    <!-- 省略其他属性 -->
</resultMap>

<select id="getUserById" resultMap="userResultMap">
    SELECT * FROM users WHERE user_id = #{id}
</select>

7. 模糊查询 like 语句该怎么写?

  • 在Java代码中添加sql的通配符。
string wildcardname =%smi%;
list<name> names = mapper.selectlike(wildcardname);

mapper.xml文件里边的SQL方法。

<select id=”selectlike”>
select * from foo where bar like #{value}
</select>
  • 在SQL中拼接通配符,
string wildcardname = “smi”;
list<name> names = mapper.selectlike(wildcardname);
<select id=”selectlike”>
select * from foo where bar like "%"#{value}"%"
</select>

8. 通常一个 Xml 映射文件,都会写一个 Dao 接口与之对应, 请问,这个 Dao 接口的工作原理是什么?Dao 接口里的方法, 参数不同时,方法能重载吗?

Dao 接口是 MyBatis 中用于与 XML 映射文件相对应的接口。它定义了操作数据库的方法,并提供了与 XML 映射文件相对应的方法名称、参数类型、返回值类型等信息,通过这些信息 MyBatis 可以根据接口的方法调用对应的 SQL 语句进行操作数据库。
Dao 接口的工作原理如下:

  • 在 XML 映射文件中定义 SQL 语句,并通过 namespace 属性指定接口的全限定名;
  • 在 Dao 接口中定义与 SQL 语句对应的方法,并指定方法的名称、参数类型和返回值类型;
  • 在配置文件中通过 标签引入 XML 映射文件,并通过 标签将 Dao 接口与 XML 映射文件进行关联;
  • 在业务代码中调用 Dao 接口的方法,MyBatis 会根据方法调用找到对应的 SQL 语句,并将参数传递给 SQL 语句进行操作数据库。
    关于 Dao 接口中方法的重载问题,Java 中允许方法重载,但是 MyBatis 不允许在 XML 映射文件中使用方法重载。因为在 XML 映射文件中,需要通过方法名来唯一确定对应的 SQL 语句,如果出现方法重载,就无法通过方法名唯一确定 SQL 语句。因此,在 Dao 接口中,虽然允许方法重载,但是在 XML 映射文件中,需要为每个方法指定不同的名称,以便能够唯一确定对应的 SQL 语句。

9. Mybatis 是如何进行分页的?分页插件的原理是什么?

  • MyBatis 支持通过 SQL 语句中的 LIMIT 关键字来实现分页查询。LIMIT 后面可以跟两个参数,第一个参数表示查询的起始行,第二个参数表示查询的记录数。
SELECT * FROM users LIMIT 10, 10;
  • 分页插件

10. Mybatis 是如何将 sql 执行结果封装为目标对象并返回的? 都有哪些映射形式?

11. 如何执行批量插入?

<insert id="batchInsert" parameterType="java.util.List">
  insert into user (name, age) values
  <foreach collection="list" item="item" separator=",">
    (#{item.name}, #{item.age})
  </foreach>
</insert>

12. 如何获取自动生成的(主)键值?

在 Mapper XML 文件中设置主键生成策略,可以使用 insert 标签的 useGeneratedKeys 属性设置主键生成策略.

<insert id="insertUser" parameterType="User" useGeneratedKeys="true" keyProperty="id">
  insert into user(name, age) values (#{name}, #{age})
</insert>

其中,useGeneratedKeys 属性为 true 表示启用主键生成策略,keyProperty 属性表示自动生成的主键值将设置到哪个属性中。

13. 在 mapper 中如何传递多个参数?

14. Mybatis 提供了哪些动态标签?

trim 、where 、set 、 foreach 、 if 、 choose、 when 、 otherwise 、 bind。

15. Xml 映射文件中,除了常见的 select|insert|updae|delete 标签之外,还有哪些标签?

resultMap、sql等

16. 一对一、一对多的关联查询 ?

  • 一对一查询指的是查询一条记录时,需要同时查询另一张表中的一条记录,且这两条记录之间有关联关系。
    定义对应Java类
public class User {
    private int id;
    private String name;
    private IdCard idCard;

    // getter 和 setter 方法省略
}
public class IdCard {
    private int id;
    private int userId;
    private String number;

    // getter 和 setter 方法省略
}

mapper.xml中的SQL语句

<resultMap id="userResultMap" type="User">
    <id column="id" property="id"/>
    <result column="name" property="name"/>
    <association property="idCard" javaType="IdCard">
        <id column="id" property="id"/>
        <result column="user_id" property="userId"/>
        <result column="number" property="number"/>
    </association>
</resultMap>
<select id="getUser" resultMap="userResultMap">
    select u.id, u.name, i.id, i.user_id, i.number
    from user u
    left join id_card i on u.id = i.user_id
    where u.id = #{id}
</select>
  • 一对多查询指的是查询一条记录时,需要同时查询另一张表中的多条记录,且这些记录都与该记录有关联关系

17. MyBatis 实现一对一有几种方式?具体怎么操作的?

有关联查询和嵌套查询。
关联查询见16问。

<!--    一对一嵌套查询-->
    <select id="selectEmpDeptInfo" resultMap="emp02">
        select * from t_emp where eid = #{id}
    </select>

    <resultMap id="emp02" type="com.zgd.pojo.Emp">
        <id column="eid" property="eid"/>
        <result property="empName" column="emp_name"/>
        <result column="age" property="age"/>
        <result column="sex" property="sex"/>
        <result column="email" property="email"/>
        <result column="did" property="did"/>
<!-- association中的   column是指的是查询回来返回的did   -->
        <association property="dept" column="did" javaType="com.zgd.pojo.Dept" select="com.zgd.mapper.DeptMapper.selectDeptInfo" />
    </resultMap>

其中需要注意一点的是association中的column需要配置为两个表相关联的属性,我的是did。这是第一条查询语句返回的字段值,在根据这个字段值传给第二条查询语句进行查询!!!。

18. MyBatis 实现一对多有几种方式,怎么操作的?

19. Mybatis 是否支持延迟加载?如果支持,它的实现原理是 什么?

20. Mybatis 的一级、二级缓存:

21. MyBatis 实现一对多有几种方式,怎么操作的?

22. Mybatis 是否支持延迟加载?如果支持,它的实现原理是 什么?

23. Mybatis 的一级、二级缓存:

24. 什么是 MyBatis 的接口绑定?有哪些实现方式?

25. 使用 MyBatis 的 mapper 接口调用时有哪些要求?

26. Mapper 编写有哪几种方式?

27. 简述 Mybatis 的插件运行原理,以及如何编写一个插件。

更多推荐

Mybatis面试题积累