MyBatis常见面试题解析(Java方向)

1. MyBatis与JDBC的区别?

MyBatis是半自动化的ORM框架,相比JDBC:

  • 自动化操作:自动管理连接池、事务和结果集映射
  • SQL解耦:SQL写在XML/注解中,与Java代码分离
  • 参数处理:自动处理参数映射和结果集转换
  • 缓存机制:提供一级/二级缓存提升性能
<!-- 示例:Mapper XML配置 -->
<select id="selectUser" resultType="User">
  SELECT * FROM users WHERE id = #{id}
</select>


2. #{}${}的区别?
  • #{}(推荐使用)
    预处理参数,自动防SQL注入,相当于JDBC的PreparedStatement
    例:WHERE name = #{name} → 编译为WHERE name = ?

  • ${}(谨慎使用)
    直接字符串替换,有SQL注入风险
    适用场景:动态表名/列名
    例:ORDER BY ${columnName}


3. 如何解决列名与属性名不一致?

三种解决方案:

  1. SQL别名
    SELECT user_name AS userName FROM t_user
    

  2. ResultMap映射
    <resultMap id="userMap" type="User">
      <result column="user_name" property="userName"/>
    </resultMap>
    

  3. 全局驼峰转换(mybatis-config.xml)
    <settings>
      <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
    


4. 一级缓存与二级缓存?
特性 一级缓存 二级缓存
作用域 SqlSession级别 Mapper级别
默认开启 需手动配置
失效场景 增删改操作/清空缓存 跨SqlSession的更新
存储位置 内存 可配置Redis等外部存储

5. 动态SQL常用标签
<select id="dynamicQuery">
  SELECT * FROM products 
  <where>
    <if test="name != null">
      AND name LIKE #{name}
    </if>
    <choose>
      <when test="category == 'electronics'">
        AND category_id = 1
      </when>
      <otherwise>
        AND category_id = 2
      </otherwise>
    </choose>
    <foreach item="id" collection="ids" open="AND id IN (" separator="," close=")">
      #{id}
    </foreach>
  </where>
</select>


6. 分页实现方式
  • 逻辑分页
    RowBounds内存分页(大数据量不推荐)
    List<User> users = sqlSession.selectList("getUsers", null, new RowBounds(10, 20));
    

  • 物理分页
    PageHelper插件(推荐)
    PageHelper.startPage(2, 10); //第2页,每页10条
    List<User> users = userMapper.selectAll();
    


7. 如何实现多表关联查询?
  • 嵌套查询(N+1问题)
    <resultMap id="orderMap" type="Order">
      <association property="user" column="user_id" select="selectUser"/>
    </resultMap>
    

  • 嵌套结果(单次查询)
    <resultMap id="orderMap" type="Order">
      <association property="user" javaType="User">
        <id property="id" column="user_id"/>
      </association>
    </resultMap>
    


8. 插件开发原理

基于责任链模式的拦截器:

@Intercepts({
  @Signature(type=Executor.class, method="query", args={...})
})
public class MyPlugin implements Interceptor {
  @Override
  public Object intercept(Invocation invocation) {
    // 前置处理
    Object result = invocation.proceed(); 
    // 后置处理
    return result;
  }
}

mybatis-config.xml注册:

<plugins>
  <plugin interceptor="com.example.MyPlugin"/>
</plugins>

提示:面试中常问实际应用场景(如分页、审计字段自动填充等)


9. 如何批量插入数据?
// Mapper接口定义
@Insert("<script>" +
        "INSERT INTO users (name) VALUES " +
        "<foreach item='user' collection='list' separator=','>" +
        "(#{user.name})" +
        "</foreach>" +
        "</script>")
void batchInsert(List<User> users);

注意:MySQL默认接受SQL长度有限制,超长需拆分批次执行


10. 延迟加载原理

通过动态代理实现关联对象的按需加载:

<settings>
  <setting name="lazyLoadingEnabled" value="true"/>
</settings>

  • 访问主对象时返回代理类
  • 当调用关联对象方法时触发SQL查询
  • 配置参数aggressiveLazyLoading控制加载行为

另外,小编还给大家准备了一套220万字的面试题题库,希望大家能够好好学习一下。

学习目录

图片

学习内容(59大专题)

Java企业架构体系相关

图片

图片

Al大模型相关

图片

图片

HR面试软技能

图片

设计模式相关

图片

并发编程相关

图片

网络IO与Netty相关

图片

互联网三高项目相关

图片

亿级流量多级缓存相关

图片

数据结构算法相关

图片

分布式相关

图片

分布式锁相关

图片

分布式ID相关

图片

核心源码相关

图片

大厂线上故障分析相关

图片

Docker相关

图片

Dubbo相关

图片

ElasticSearch相关

图片

GoLang相关

图片

Java基础核心

图片

JVM核心相关

图片

JVM调优底层相关

图片

Kafka相关

图片

Kubernetes相关

图片

Linux相关

图片

MongoDB相关

图片

MQ相关

图片

MySQL相关

图片

MyBatis相关

图片

MyBatisPlus相关

图片

Neo4j相关

图片

Netty相关

图片

Nginx相关

图片

Oracle相关

图片

postgresql相关

图片

RabbitMQ相关

图片

RocketMQ相关

图片

Redis相关

图片

shardingSphere相关

图片

shiro相关

图片

skywalking相关

图片

Solr相关

图片

Spring相关

图片

SpringBoot相关

图片

SpringCloud相关

图片

SpringMVc源码相关

图片

springSecurity相关

图片

Spring WebFlux相关

图片

领域驱动设计(DDD)相关

图片

任务调度Airflow相关

图片

zookeeper相关

图片

HDFS面试题

图片

MapReduce面试题

图片

Yarn面试题

图片

大数据SQL面试题

图片

Scala面试题

图片

Spark面试题

图片

Tomcat源码

图片

相关网络安全相关

图片

运维/云原生相关

图片

结束语

图片

已经整理成册,需要的同学查看下方名片拿走了!

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐