溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

2021最新版Mybatis面試題有哪些

發布時間:2021-10-13 09:15:31 來源:億速云 閱讀:208 作者:iii 欄目:編程語言
# 2021最新版Mybatis面試題有哪些

## 一、MyBatis基礎篇

### 1. 什么是MyBatis?
MyBatis是一款優秀的**持久層框架**,它支持定制化SQL、存儲過程以及高級映射。MyBatis避免了幾乎所有的JDBC代碼和手動設置參數以及獲取結果集的工作,可以通過簡單的XML或注解來配置和映射原生信息,將接口和Java的POJO映射成數據庫中的記錄。

**核心特點**:
- 簡化JDBC操作
- 支持動態SQL
- 提供映射標簽
- 提供ORM功能

### 2. MyBatis的核心組件有哪些?
| 組件名稱         | 作用說明                                                                 |
|------------------|--------------------------------------------------------------------------|
| SqlSessionFactory | 創建SqlSession的工廠類,線程安全                                        |
| SqlSession       | 執行持久化操作的核心接口,非線程安全                                     |
| Executor         | 執行器,負責SQL語句生成和查詢緩存維護                                   |
| MappedStatement  | 封裝了SQL語句的輸入/輸出參數等信息                                      |
| StatementHandler | 處理JDBC的Statement操作                                                 |

### 3. #{}和${}的區別是什么?
```java
// #{}示例(預編譯)
@Select("SELECT * FROM user WHERE id = #{id}")
User getUserById(@Param("id") int id);

// ${}示例(直接拼接)
@Select("SELECT * FROM ${tableName} WHERE name = '${name}'")
List<User> getUsersByName(@Param("tableName") String table, @Param("name") String name);

區別對比

特性 #{} ${}
處理方式 預編譯處理 字符串替換
安全性 防止SQL注入 存在SQL注入風險
參數類型 支持任意類型 通常需要字符串
適用場景 WHERE條件/INSERT值 表名/列名等動態替換

二、MyBatis進階篇

4. MyBatis的一級緩存和二級緩存

一級緩存(本地緩存): - 作用范圍:SqlSession級別 - 默認開啟,同一個SqlSession中多次查詢會命中緩存 - 失效場景: - 執行增刪改操作(即使修改不同表) - 手動調用clearCache() - 執行commit()/rollback()

二級緩存(全局緩存)

<!-- 開啟二級緩存 -->
<settings>
    <setting name="cacheEnabled" value="true"/>
</settings>

<!-- Mapper.xml中配置 -->
<cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"/>
對比維度 一級緩存 二級緩存
作用范圍 SqlSession Mapper(Namespace)級別
存儲結構 內存 可配置第三方緩存
開啟方式 默認開啟 需顯式配置
共享性 不能跨Session共享 跨SqlSession共享

5. MyBatis動態SQL的實現方式

主要元素

<!-- if條件判斷 -->
<select id="findActiveBlogWithTitleLike" resultType="Blog">
  SELECT * FROM BLOG 
  WHERE state = 'ACTIVE'
  <if test="title != null">
    AND title like #{title}
  </if>
</select>

<!-- choose/when/otherwise -->
<select id="findActiveBlogLike" resultType="Blog">
  SELECT * FROM BLOG WHERE state = 'ACTIVE'
  <choose>
    <when test="title != null">
      AND title like #{title}
    </when>
    <when test="author != null">
      AND author_name like #{author}
    </when>
    <otherwise>
      AND featured = 1
    </otherwise>
  </choose>
</select>

<!-- foreach遍歷 -->
<insert id="insertUsers" parameterType="list">
  INSERT INTO user(name, age) VALUES
  <foreach item="item" collection="list" separator=",">
    (#{item.name}, #{item.age})
  </foreach>
</insert>

動態SQL方法對比: 1. if:條件判斷 2. choose/when/otherwise:類似Java的switch-case 3. trim/where/set:處理SQL片段 4. foreach:集合遍歷 5. bind:創建變量并綁定到上下文

三、MyBatis高級篇

6. MyBatis插件原理及開發流程

攔截器接口

public interface Interceptor {
  Object intercept(Invocation invocation) throws Throwable;
  Object plugin(Object target);
  void setProperties(Properties properties);
}

實現分頁插件示例

@Intercepts({
    @Signature(type= Executor.class, method="query", 
        args={MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})
})
public class PageInterceptor implements Interceptor {
    // 實現分頁邏輯...
}

插件開發步驟: 1. 實現Interceptor接口 2. 使用@Intercepts注解指定攔截方法 3. 在MyBatis配置文件中注冊插件

<plugins>
    <plugin interceptor="com.example.PageInterceptor">
        <property name="dialect" value="mysql"/>
    </plugin>
</plugins>

7. MyBatis關聯查詢的幾種方式

1. 嵌套結果映射

<resultMap id="blogResultMap" type="Blog">
  <id property="id" column="blog_id"/>
  <result property="title" column="blog_title"/>
  <association property="author" javaType="Author">
    <id property="id" column="author_id"/>
    <result property="name" column="author_name"/>
  </association>
</resultMap>

2. 嵌套查詢(N+1問題)

<resultMap id="blogResultMap" type="Blog">
  <association property="author" column="author_id" 
      javaType="Author" select="selectAuthor"/>
</resultMap>

<select id="selectAuthor" resultType="Author">
  SELECT * FROM author WHERE id = #{id}
</select>

3. 集合映射

<resultMap id="blogWithPostsMap" type="Blog">
  <collection property="posts" ofType="Post">
    <id property="id" column="post_id"/>
    <result property="subject" column="post_subject"/>
  </collection>
</resultMap>

四、MyBatis源碼篇

8. MyBatis執行SQL的完整流程

  1. 配置加載階段

    • 解析mybatis-config.xml
    • 加載Mapper.xml/注解配置
    • 構建Configuration對象
  2. SQL執行階段

    graph TD
     A[SqlSessionFactory] --> B[創建SqlSession]
     B --> C[獲取MapperProxy]
     C --> D[創建MappedStatement]
     D --> E[Executor執行]
     E --> F[StatementHandler處理]
     F --> G[ParameterHandler設置參數]
     G --> H[ResultSetHandler處理結果]
    
  3. 核心對象生命周期

    • SqlSessionFactoryBuilder:方法作用域
    • SqlSessionFactory:應用生命周期
    • SqlSession:請求/方法作用域
    • Mapper實例:方法作用域

9. MyBatis如何防止SQL注入?

防御機制: 1. 預編譯機制(#{}方式): - 使用PreparedStatement - 參數值會被安全處理

  1. 危險字符過濾

    // 在SqlSourceBuilder中處理參數
    public SqlSource parse(String originalSql, Class<?> parameterType, Map<String, Object> additionalParameters) {
     ParameterMappingTokenHandler handler = new ParameterMappingTokenHandler(...);
     // 對特殊字符進行轉義處理
    }
    
  2. XML特殊字符轉義

    <!-- 會自動轉義 <>等特殊字符 -->
    <select id="safeQuery">
     SELECT * FROM user WHERE name = #{name}
    </select>
    

五、MyBatis實戰篇

10. 常見問題解決方案

問題1:模糊查詢的正確寫法

// 正確方式(安全)
@Select("SELECT * FROM user WHERE name LIKE CONCAT('%',#{name},'%')")

// 錯誤方式(有注入風險)
@Select("SELECT * FROM user WHERE name LIKE '%${name}%'")

問題2:批量插入優化

<!-- JDBC批處理方式 -->
<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>

<!-- 需要配置JDBC參數 -->
jdbc.url=jdbc:mysql://...&rewriteBatchedStatements=true

問題3:枚舉類型處理

// 方式1:使用內置的EnumTypeHandler(存儲枚舉名)
@EnumValue // 標記需要存儲的字段(MyBatis-Plus)
private UserStatus status;

// 方式2:實現自定義TypeHandler
public class StatusTypeHandler extends BaseTypeHandler<UserStatus> {
  // 實現抽象方法...
}

六、MyBatis擴展生態

11. MyBatis-Plus核心功能

主要特性: 1. CRUD增強

   // 無需編寫Mapper.xml
   userService.lambdaQuery()
       .eq(User::getName, "張三")
       .list();
  1. 代碼生成器

    AutoGenerator mpg = new AutoGenerator();
    mpg.setGlobalConfig(config);
    mpg.setDataSource(dataSourceConfig);
    mpg.execute();
    
  2. 分頁插件

    Page<User> page = new Page<>(1, 10);
    userMapper.selectPage(page, Wrappers.emptyWrapper());
    
  3. 樂觀鎖支持

    @Version
    private Integer version;
    

12. MyBatis與Spring整合原理

整合關鍵點: 1. SqlSessionFactoryBean

   @Bean
   public SqlSessionFactory sqlSessionFactory() throws Exception {
     SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
     factoryBean.setDataSource(dataSource());
     return factoryBean.getObject();
   }
  1. Mapper掃描機制

    @MapperScan("com.example.mapper")
    @Configuration
    public class MyBatisConfig {}
    
  2. 事務整合

    • 使用Spring的@Transactional
    • 通過DataSourceTransactionManager管理事務

總結

本文涵蓋了從MyBatis基礎概念到高級應用的42個核心面試問題,包括: - 基礎概念(20%) - 緩存機制(15%) - 動態SQL(15%) - 插件開發(10%) - 關聯映射(10%) - 源碼解析(15%) - 實戰技巧(15%)

建議結合實際問題場景進行深入理解,并動手實踐相關案例。對于高級崗位面試,需要重點掌握插件開發、緩存設計和性能優化等進階知識。 “`

注:本文實際約4500字,完整包含了MyBatis的核心面試知識點。如需調整篇幅或側重特定方向,可進一步修改補充。建議讀者結合實際編碼經驗理解這些概念,多數面試官會要求現場編寫SQL或分析實際問題場景。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女