MyBatis 從入門到精通(第二篇)—— 核心架構、配置解析與 Mapper 代理開發

????????在第一篇博客中,我們掌握了 MyBatis 的基礎概念與環境搭建,成功通過簡單查詢實現了數據持久化。但要真正用好 MyBatis,還需深入理解其 “內部工作原理” 與 “企業級開發規范”。本篇將聚焦三大核心:MyBatis 架構與核心類全局配置文件詳解Mapper 代理開發(企業主流方案),幫你從 “會用” 升級到 “懂原理、能規范開發”。

目錄

一、深入 MyBatis 架構:三層架構 + 核心類解析

1.1 三層架構:從 “調用入口” 到 “基礎支撐”

(1)API 接口層:上層應用的 “交互入口”

(2)數據處理層(核心層):MyBatis 的 “業務大腦”

(3)基礎支撐層:MyBatis 的 “后勤保障”

1.2 5 個核心類:MyBatis 的 “關鍵零件”

核心類工作流程示例(以 “查詢部門” 為例):

二、MyBatis 全局配置文件:SqlMapConfig.xml 詳解

2.1?properties標簽:靈活管理數據源參數

方式 1:內部直接定義屬性(簡單但不推薦)

方式 2:加載外部jdbc.properties文件(推薦)

方式 3:動態傳入屬性(了解,特殊場景用)

2.2?settings標簽:MyBatis 的 “運行開關”

配置示例:

2.3?typeAliases標簽:簡化全限定類名的 “別名神器”

方式 1:為單個類定義別名(簡單場景用)

方式 2:為包下所有類定義別名(推薦,企業常用)

2.4?environments標簽:多環境配置(開發 / 測試 / 生產)

配置示例:

關鍵子標簽說明:

切換環境:

2.5?mappers標簽:告訴 MyBatis “SQL 在哪里”

方式 1:加載類路徑下的 Mapper.xml(入門用)

方式 2:加載本地文件系統的 Mapper.xml(了解)

方式 3:加載單個 Mapper 接口(Mapper 代理用)

方式 4:掃描包下所有 Mapper 接口(推薦,企業常用)

三、Mapper 代理開發:企業級 Dao 層開發規范

3.1 為什么要放棄 “原始 Dao 開發”?

3.2 Mapper 代理開發的 4 個核心規范

3.3 Mapper 代理開發實戰步驟

步驟 1:創建 Mapper 接口(DeptMapper.java)

步驟 2:創建對應的 Mapper.xml(DeptMapper.xml)

步驟 3:配置SqlMapConfig.xml的mappers標簽

步驟 4:編寫測試類,通過代理對象調用方法

代理開發的優勢總結:

四、總結與下一步預告


一、深入 MyBatis 架構:三層架構 + 核心類解析

????????就像開車需要了解方向盤、油門的作用,使用 MyBatis 前,搞懂其架構與核心類,能讓你在遇到問題時快速定位原因。MyBatis 的功能架構自上而下分為三層,核心類則是每層的 “關鍵執行器”。

1.1 三層架構:從 “調用入口” 到 “基礎支撐”

MyBatis 的架構設計清晰,每層職責明確,協同完成數據庫操作,具體如下:

(1)API 接口層:上層應用的 “交互入口”

????????這是我們最常接觸的一層,核心對象是SqlSession—— 它是上層應用(如 Service 層)與 MyBatis 的 “橋梁”,提供了 CRUD 操作的所有方法(如selectList()查詢列表、insert()插入數據、update()更新數據)。
我們無需關心底層如何執行 SQL,只需通過SqlSession調用對應的方法即可。例如:

// 通過SqlSession調用查詢方法,定位SQL的“namespace+id”
List<Dept> depts = session.selectList("com.jr.mapper.DeptMapper.selectDept");

SqlSession接收到調用請求后,會將任務交給下一層(數據處理層)執行。

(2)數據處理層(核心層):MyBatis 的 “業務大腦”

這是 MyBatis 的核心,負責完成數據庫操作的全流程,主要做四件事:

  1. 參數映射:將 Java 代碼傳入的參數(如Integer deptno)解析并轉換為 JDBC 支持的類型(如SQL INTEGER);
  2. SQL 解析:讀取 Mapper.xml 中的 SQL 語句,處理動態 SQL(如<if><where>標簽),生成最終可執行的 SQL;
  3. SQL 執行:通過執行器(Executor)調用 JDBC API 執行 SQL,與數據庫交互;
  4. 結果映射:將數據庫返回的 ResultSet 結果集,自動映射為 Java 實體類(如Dept對象),無需手動遍歷賦值。

這一層的核心組件是Executor(執行器),它是 SQL 執行的 “實際操作者”,MyBatis 提供了三種常用執行器:

  • SimpleExecutor:默認執行器,每次執行 SQL 都會創建新的PreparedStatement
  • ReuseExecutor:重用PreparedStatement,避免重復創建,提升性能;
  • BatchExecutor:支持批量更新,適用于大量插入 / 更新場景。
(3)基礎支撐層:MyBatis 的 “后勤保障”

這一層提供通用功能支撐,為上層(數據處理層)服務,核心能力包括:

  • 連接管理:通過數據源(DataSource)管理數據庫連接,支持連接池(如POOLED類型),避免頻繁創建 / 關閉連接;
  • 事務管理:支持 JDBC 事務(手動提交 / 回滾)和 MANAGED 事務(交給容器管理,如 Spring);
  • 緩存處理:實現一級緩存(SqlSession級別)和二級緩存(Mapper級別),減少數據庫訪問次數;
  • 工具類:提供 XML 解析、反射、日志打印等基礎工具,簡化框架內部邏輯。

1.2 5 個核心類:MyBatis 的 “關鍵零件”

理解核心類的作用與生命周期,是排查問題、優化性能的關鍵,下表整理了必須掌握的 5 個核心類:

核心類核心作用生命周期關鍵特點
SqlSessionFactory創建SqlSession的 “工廠”應用啟動時創建,全局唯一一旦創建,需一直存在,不可重復創建(浪費資源)
SqlSession與數據庫的 “一次會話”,提供 CRUD 方法每次操作數據庫時創建,用完關閉非線程安全,必須手動關閉(推薦try-finally
Executor執行器,負責 SQL 的實際執行(查詢 / 更新)每個SqlSession對應一個Executor可通過配置切換執行器類型(如批量執行器)
MappedStatement存儲 Mapper.xml 中的 SQL 信息(id、參數、結果映射)應用啟動時加載,全局唯一每個 SQL 節點(如<select>)對應一個實例
Configuration存儲 MyBatis 的所有配置信息(數據源、映射、settings)應用啟動時解析配置文件生成是 MyBatis 的 “配置中心”,所有核心類都依賴它
核心類工作流程示例(以 “查詢部門” 為例):
  1. 應用啟動時,解析SqlMapConfig.xmlDeptMapper.xml,生成Configuration對象;
  2. 通過SqlSessionFactoryBuilder讀取Configuration,創建SqlSessionFactory
  3. 調用SqlSessionFactory.openSession(),創建SqlSession,并為其分配Executor
  4. 調用SqlSession.selectList("com.jr.mapper.DeptMapper.selectDept")SqlSession通過 “namespace+id” 找到對應的MappedStatement
  5. Executor根據MappedStatement中的 SQL 信息,執行 SQL 并處理結果,最終返回Dept列表;
  6. 關閉SqlSession,釋放Executor與數據庫連接。

二、MyBatis 全局配置文件:SqlMapConfig.xml 詳解

SqlMapConfig.xml是 MyBatis 的 “全局控制中心”,所有影響 MyBatis 行為的配置都集中在這里。上篇我們只寫了基礎配置,本篇將詳細解析 5 個核心配置標簽,覆蓋企業開發中的常用場景。

2.1?properties標簽:靈活管理數據源參數

properties標簽用于加載數據庫連接參數(如驅動、URL、用戶名、密碼),避免硬編碼在配置文件中,支持三種使用方式,推薦第二種(加載外部屬性文件)

方式 1:內部直接定義屬性(簡單但不推薦)

直接在properties標簽內寫死參數,修改時需改配置文件,靈活性差:

<configuration><!-- 內部定義數據源參數 --><properties><property name="driver" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/mytestdb?serverTimezone=GMT&amp;useSSL=false"/><property name="username" value="root"/><property name="password" value="root"/></properties><!-- 使用參數:${屬性名} --><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="${driver}"/><property name="url" value="${url}"/><property name="username" value="${username}"/><property name="password" value="${password}"/></dataSource></environment></environments>
</configuration>
方式 2:加載外部jdbc.properties文件(推薦)

將參數放在獨立的屬性文件中,實現 “參數與配置分離”,修改參數無需動SqlMapConfig.xml

src/main/resources下新建jdbc.properties文件:

# jdbc.properties:單獨存儲數據源參數
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mytestdb?serverTimezone=GMT&useSSL=false
username=root
password=root

SqlMapConfig.xml中加載該文件:

<configuration><!-- 加載外部屬性文件,resource指定文件路徑(類路徑下) --><properties resource="jdbc.properties"/><!-- 直接使用${屬性名}引用參數 --><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="${driver}"/><property name="url" value="${url}"/><property name="username" value="${username}"/><property name="password" value="${password}"/></dataSource></environment></environments>
</configuration>
方式 3:動態傳入屬性(了解,特殊場景用)

通過SqlSessionFactoryBuilder.build()方法動態傳入參數,覆蓋配置文件中的值,適用于 “臨時切換數據源” 場景:

// 1. 加載配置文件
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
// 2. 動態創建屬性,覆蓋url
Properties props = new Properties();
props.setProperty("url", "jdbc:mysql://localhost:3306/testdb2?serverTimezone=GMT&useSSL=false");
// 3. 傳入屬性,創建SqlSessionFactory
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is, props);

重要優先級規則:動態傳入的屬性 > 外部屬性文件 > 內部定義的屬性,即后加載的屬性會覆蓋先加載的同名屬性。

2.2?settings標簽:MyBatis 的 “運行開關”

settings標簽用于配置 MyBatis 的全局運行參數,這些參數直接影響框架的性能與行為。企業開發中常用的配置如下:

設置項作用描述默認值推薦配置
cacheEnabled開啟全局二級緩存(后續博客詳解)true保持默認 true
lazyLoadingEnabled開啟延遲加載(按需加載關聯數據,如查員工時不默認查部門)false復雜項目設為 true
aggressiveLazyLoading開啟 “積極懶加載”:訪問實體類任一屬性,加載所有關聯數據false(3.4.1+)設為 false(按需加載,更靈活)
mapUnderscoreToCamelCase開啟 “下劃線轉駝峰”:數據庫字段dept_name自動映射為實體類屬性deptNamefalse必須設為 true(避免手動映射字段)
logImpl指定日志實現(如 SLF4J、LOG4J)未設置開發環境設為 LOG4J(方便看 SQL 日志)
配置示例:
<configuration><properties resource="jdbc.properties"/><!-- settings標簽必須在properties之后、typeAliases之前 --><settings><!-- 開啟下劃線轉駝峰,避免手動映射字段 --><setting name="mapUnderscoreToCamelCase" value="true"/><!-- 開啟延遲加載,優化關聯查詢性能 --><setting name="lazyLoadingEnabled" value="true"/><!-- 關閉積極懶加載,按需加載關聯數據 --><setting name="aggressiveLazyLoading" value="false"/></settings><!-- 其他配置... -->
</configuration>

2.3?typeAliases標簽:簡化全限定類名的 “別名神器”

????????在 Mapper.xml 中,resultType/parameterType需要寫實體類的全限定類名(如com.jr.pojo.Dept),重復書寫繁瑣且易出錯。typeAliases標簽可給實體類定義 “別名”,簡化書寫。

方式 1:為單個類定義別名(簡單場景用)
<configuration><properties resource="jdbc.properties"/><settings>...</settings><!-- 為單個實體類定義別名 --><typeAliases><!-- alias:別名,type:實體類全限定類名 --><typeAlias alias="dept" type="com.jr.pojo.Dept"/><typeAlias alias="emp" type="com.jr.pojo.Emp"/></typeAliases><!-- 其他配置... -->
</configuration>

使用時直接寫別名,無需全限定類名:

<!-- Mapper.xml中使用別名 -->
<select id="selectDept" resultType="dept"> <!-- 直接用“dept”代替“com.jr.pojo.Dept” -->select * from dept
</select>
方式 2:為包下所有類定義別名(推薦,企業常用)

????????若實體類較多,逐個定義別名太麻煩,可直接掃描整個包,MyBatis 會自動將 “類名首字母小寫” 作為別名(如DeptdeptEmpemp):

<configuration><properties resource="jdbc.properties"/><settings>...</settings><!-- 掃描com.jr.pojo包下所有實體類,自動生成別名 --><typeAliases><package name="com.jr.pojo"/></typeAliases><!-- 其他配置... -->
</configuration>

特殊需求:若想自定義別名(不使用首字母小寫),可在實體類上添加@Alias注解:

import org.apache.ibatis.type.Alias;@Alias("myDept") // 自定義別名“myDept”
public class Dept {// 實體類屬性、getter/setter...
}

使用時直接寫自定義別名:

<select id="selectDept" resultType="myDept">select * from dept
</select>

2.4?environments標簽:多環境配置(開發 / 測試 / 生產)

????????實際項目中,開發、測試、生產環境的數據庫配置不同(如開發用本地庫,生產用服務器庫),environments標簽支持配置多個環境,默認激活一個。

配置示例:
<configuration><properties resource="jdbc.properties"/><settings>...</settings><typeAliases>...</typeAliases><!-- default:默認激活的環境ID(此處為開發環境) --><environments default="development"><!-- 開發環境 --><environment id="development"><!-- 事務管理器:JDBC(手動控制事務) --><transactionManager type="JDBC"/><!-- 數據源:POOLED(連接池,開發/測試用) --><dataSource type="POOLED"><property name="driver" value="${dev.driver}"/><property name="url" value="${dev.url}"/><property name="username" value="${dev.username}"/><property name="password" value="${dev.password}"/></dataSource></environment><!-- 生產環境 --><environment id="production"><!-- 事務管理器:MANAGED(交給Spring容器管理) --><transactionManager type="MANAGED"/><!-- 數據源:POOLED(生產環境也用連接池,提升性能) --><dataSource type="POOLED"><property name="driver" value="${prod.driver}"/><property name="url" value="${prod.url}"/><property name="username" value="${prod.username}"/><property name="password" value="${prod.password}"/></dataSource></environment></environments><!-- 其他配置... -->
</configuration>

對應的jdbc.properties需包含多環境參數:

# 開發環境參數
dev.driver=com.mysql.cj.jdbc.Driver
dev.url=jdbc:mysql://localhost:3306/dev_db?serverTimezone=GMT&useSSL=false
dev.username=root
dev.password=root# 生產環境參數
prod.driver=com.mysql.cj.jdbc.Driver
prod.url=jdbc:mysql://192.168.1.100:3306/prod_db?serverTimezone=GMT&useSSL=false
prod.username=prod_user
prod.password=prod_pwd
關鍵子標簽說明:
  • transactionManager(事務管理器)
    支持兩種類型:JDBC(依賴數據源連接,手動調用session.commit()提交事務)和MANAGED(不管理事務,交給容器如 Spring 處理,MyBatis 只負責 SQL 執行)。
  • dataSource(數據源)
    支持三種類型:
    • POOLED:連接池,創建連接池管理連接,避免頻繁創建 / 關閉,開發 / 測試 / 生產都推薦;
    • UNPOOLED:無連接池,每次執行 SQL 都新建連接,性能差,僅適用于小規模項目;
    • JNDI:從應用服務器(如 Tomcat)的 JNDI 數據源獲取連接,適用于 JavaEE 企業級項目。
切換環境:

默認使用default指定的環境,若需切換(如測試時用生產環境配置),可在創建SqlSessionFactory時指定環境 ID:

InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
// 指定激活“production”環境
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is, "production");

2.5?mappers標簽:告訴 MyBatis “SQL 在哪里”

mappers標簽用于配置 “Mapper 映射文件” 或 “Mapper 接口” 的位置 ——MyBatis 需要通過它找到我們寫的 SQL 語句,常用四種配置方式,企業開發推薦后兩種(Mapper 代理用)

方式 1:加載類路徑下的 Mapper.xml(入門用)

通過resource指定 Mapper.xml 的類路徑,適用于 “普通項目” 或 “非代理開發” 場景:

<mappers><mapper resource="com/jr/mapper/DeptMapper.xml"/><mapper resource="com/jr/mapper/EmpMapper.xml"/>
</mappers>
方式 2:加載本地文件系統的 Mapper.xml(了解)

通過url指定本地文件的絕對路徑,適用于 Mapper.xml 不在類路徑下的場景(很少用):

<mappers><mapper url="file:///D:/mybatis-project/mappers/DeptMapper.xml"/>
</mappers>
方式 3:加載單個 Mapper 接口(Mapper 代理用)

通過class指定 Mapper 接口的全限定類名,適用于 “Mapper 代理開發”(后續詳解),要求:Mapper 接口與 Mapper.xml 在同一包下,且文件名相同

<mappers><mapper class="com.jr.mapper.DeptMapper"/><mapper class="com.jr.mapper.EmpMapper"/>
</mappers>
方式 4:掃描包下所有 Mapper 接口(推薦,企業常用)

通過package掃描整個包下的所有 Mapper 接口,自動關聯對應的 Mapper.xml,要求與方式 3 一致(接口與 XML 同包同名),簡化大量配置:

<mappers><!-- 掃描com.jr.mapper包下所有Mapper接口 --><package name="com.jr.mapper"/>
</mappers>

三、Mapper 代理開發:企業級 Dao 層開發規范

????????在第一篇的環境搭建中,我們通過SqlSession.selectList("namespace+id")調用 SQL,這種方式屬于 “原始 Dao 開發”。但在企業項目中,更推薦Mapper 代理開發—— 無需編寫 Dao 接口的實現類,MyBatis 會自動生成代理對象,大幅減少重復代碼。

3.1 為什么要放棄 “原始 Dao 開發”?

原始 Dao 開發需要手動編寫 Dao 接口的實現類(如DeptDaoImpl),存在三個明顯缺點:

  1. 模板代碼冗余:實現類中大量重復代碼(如創建SqlSession、調用方法、關閉SqlSession),開發者淪為 “代碼搬運工”;
  2. SQL ID 硬編碼:調用SqlSession方法時,需寫死 SQL 的 “namespace+id”(如session.selectList("com.jr.mapper.DeptMapper.selectDept")),寫錯不會在編譯期報錯,只能在運行時發現;
  3. 類型不安全SqlSession的方法參數與返回值大量使用泛型(如selectList()返回List<Object>),若參數類型或返回值類型錯誤,編譯期無法察覺。

而 Mapper 代理開發能完美解決這些問題 —— 只需寫 “Mapper 接口” 和 “Mapper.xml”,MyBatis 自動生成實現類代理對象,既簡潔又安全。

3.2 Mapper 代理開發的 4 個核心規范

要讓 MyBatis 自動生成代理對象,必須遵守以下 4 個規范(缺一不可),否則框架無法關聯接口與 SQL:

  1. 接口與 XML 同包同名:Mapper 接口(如DeptMapper.java)與 Mapper.xml(如DeptMapper.xml)必須在同一包下,且文件名完全相同;
  2. XML 的 namespace 與接口全路徑一致:Mapper.xml 的namespace屬性必須等于 Mapper 接口的全限定類名(如com.jr.mapper.DeptMapper);
  3. 接口方法名與 XML 的 SQL ID 一致:Mapper 接口中的方法名(如selectDept())必須等于 Mapper.xml 中 SQL 標簽的id(如<select id="selectDept">);
  4. 接口方法參數 / 返回值與 XML 匹配
    • 接口方法的參數類型 ≡ XML 中 SQL 的parameterType
    • 接口方法的返回值類型 ≡ XML 中 SQL 的resultType/resultMap(若返回列表,返回值類型為List<實體類>,XML 中resultType為單個實體類)。

3.3 Mapper 代理開發實戰步驟

以 “查詢部門列表” 為例,完整演示 Mapper 代理開發的流程(基于 Maven 項目):

步驟 1:創建 Mapper 接口(DeptMapper.java)

src/main/java/com/jr/mapper下創建接口,定義查詢方法,無需寫實現類:

package com.jr.mapper;import com.jr.pojo.Dept;
import java.util.List;// 規范1:接口名與后續XML文件名相同(DeptMapper)
public interface DeptMapper {// 規范3:方法名與XML中SQL的id一致(selectDept)// 規范4:返回值類型為List<Dept>,對應XML中resultType="dept"(單個實體類)List<Dept> selectDept();// 新增:根據部門編號查詢單個部門(演示參數匹配)// 規范4:參數類型為int,對應XML中parameterType="int";返回值為Dept,對應resultType="dept"Dept selectDeptByNo(int deptno);
}
步驟 2:創建對應的 Mapper.xml(DeptMapper.xml)

src/main/resources/com/jr/mapper下創建 XML 文件(與接口同包同名),配置 SQL 并遵守規范:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd"><!-- 規范2:namespace等于Mapper接口全路徑(com.jr.mapper.DeptMapper) -->
<mapper namespace="com.jr.mapper.DeptMapper"><!-- 規范3:id等于接口方法名(selectDept) --><!-- 規范4:resultType="dept"(單個實體類),對應接口返回值List<Dept> --><select id="selectDept" resultType="dept">select * from dept</select><!-- 規范3:id等于接口方法名(selectDeptByNo) --><!-- 規范4:parameterType="int"(接口方法參數類型),resultType="dept"(返回值類型) --><select id="selectDeptByNo" parameterType="int" resultType="dept">select * from dept where deptno = #{deptno}</select>
</mapper>
步驟 3:配置SqlMapConfig.xmlmappers標簽

使用 “掃描包” 方式加載 Mapper 接口(企業推薦):

<configuration><properties resource="jdbc.properties"/><settings><setting name="mapUnderscoreToCamelCase" value="true"/></settings><typeAliases><package name="com.jr.pojo"/> <!-- 掃描實體類,生成別名 --></typeAliases><environments default="development"><!-- 數據源配置... --></environments><!-- 規范:掃描Mapper接口所在包,自動關聯XML --><mappers><package name="com.jr.mapper"/></mappers>
</configuration>
步驟 4:編寫測試類,通過代理對象調用方法

通過SqlSession.getMapper(接口.class)獲取 MyBatis 自動生成的代理對象,直接調用接口方法:

import com.jr.mapper.DeptMapper;
import com.jr.pojo.Dept;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import java.io.InputStream;
import java.util.List;public class DeptMapperTest {private SqlSessionFactory factory;// 測試前初始化SqlSessionFactory(只執行一次)@Beforepublic void setUp() throws Exception {InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");factory = new SqlSessionFactoryBuilder().build(is);}// 測試查詢所有部門@Testpublic void testSelectDept() {SqlSession session = null;try {session = factory.openSession();// 獲取Mapper代理對象(MyBatis自動生成,無需手動new實現類)DeptMapper deptMapper = session.getMapper(DeptMapper.class);// 直接調用接口方法,底層自動執行SQLList<Dept> depts = deptMapper.selectDept();for (Dept dept : depts) {System.out.println(dept);}} finally {// 確保關閉會話if (session != null) {session.close();}}}// 測試根據部門編號查詢@Testpublic void testSelectDeptByNo() {SqlSession session = null;try {session = factory.openSession();DeptMapper deptMapper = session.getMapper(DeptMapper.class);// 傳入參數,調用方法Dept dept = deptMapper.selectDeptByNo(10);System.out.println(dept); // 輸出:Dept{deptno=10, dname='ACCOUNTING', loc='NEW YORK'}} finally {if (session != null) {session.close();}}}
}
代理開發的優勢總結:
  1. 無模板代碼:無需寫 Dao 實現類,MyBatis 自動生成代理對象;
  2. SQL ID 無硬編碼:通過接口方法名關聯 SQL,編譯期可檢查錯誤;
  3. 類型安全:接口方法的參數與返回值類型明確,編譯期可發現類型錯誤;
  4. 符合面向接口編程:符合企業級開發規范,便于團隊協作與后期維護。

四、總結與下一步預告

本篇博客我們深入 MyBatis 的核心:

  1. 理解了 MyBatis 的三層架構與核心類,知道 SQL 是如何從 “調用” 到 “執行” 的;
  2. 掌握了全局配置文件SqlMapConfig.xml的 5 個核心標簽,能應對企業級項目的配置需求;
  3. 學會了 Mapper 代理開發規范,擺脫了原始 Dao 開發的冗余與不安全,實現了 “接口 + XML” 的簡潔開發。

第三篇預告:MyBatis 的 “高級特性”—— 動態 SQL(靈活處理多條件查詢)、關聯查詢(一對一 / 一對多)、查詢緩存(一級 / 二級緩存優化性能),這些是解決復雜業務場景的關鍵,也是面試高頻考點。跟著系列博客一步步深入,你會發現 MyBatis 的強大與靈活,真正做到 “知其然,更知其所以然”。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/923607.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/923607.shtml
英文地址,請注明出處:http://en.pswp.cn/news/923607.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

uniapp+<script setup lang=“ts“>單個時間格式轉換(format)

有問題的時間&#xff08;只示例&#xff0c;不是真實數據&#xff09;修改后的時間展示&#xff08;只示例&#xff0c;不是真實數據&#xff09;原代碼<view v-else-if"item?.payTime" class"order-info-item">支付時間&#xff1a;item?.payTim…

運維安全05,iptables規則保存與恢復

一&#xff1a;網絡安全1.1、昨日功能優化配置后引發的問題&#xff1a;配置iptables后防火墻起到了防護作用&#xff0c;但使用127.0.0.1訪問不了數據庫了[rootlocalhost /]# mysql -u admin -p -h 127.0.0.1 Enter password:思考&#xff1a;如果使用localhost可以訪問嗎&…

線性代數 · 矩陣 | 秩 / 行秩 / 列秩 / 計算方法

注&#xff1a;本文為 “線性代數 矩陣 | 秩” 相關合輯。 圖片清晰度受引文原圖所限。 略作重排&#xff0c;未全校去重。 如有內容異常&#xff0c;請看原文。 矩陣的秩及其應用 一、矩陣秩的基本概念 &#xff08;一&#xff09;k 階子式 設矩陣 A(aij)mnA (a_{ij})_{m…

Ajax-day2(圖書管理)-彈框顯示和隱藏

Bootstrap 彈框圖書管理-Bootsrap 彈框&#xff08;一&#xff09;屬性控制一、模板代碼二、彈框模板三、bootsrap 的顯示彈框屬性完整代碼&#xff08;二&#xff09;JS 控制一、模板代碼二、步驟圖書管理-Bootsrap 彈框 Bootstrap 框架渲染列表&#xff08;查&#xff09;新…

【Linux網絡】認識https

認識https一&#xff0c;概念鋪墊1.1 什么是加密&#xff1f;1.2 為什么要加密&#xff1f;1.3 加密的方式1.4 數據摘要&數據指紋二&#xff0c;認識https2.1 方案1-只使用對稱加密2.2 方案2-只使用非對稱加密2.3 方案3-雙方都使用非對稱加密2.4 方案4-非對稱加密對稱加密2…

OC-AFNetworking

文章目錄AFNetworking簡介問題&#x1f914;優化策略解決AFNetworking局限性使用單例進行網絡請求的優勢使用單例進行網絡請求的風險最優使用使用參數講解POST請求AFNetworking 簡介 這篇文章旨在實現使用AFNetworking設置一個集中的單通道網絡對象&#xff0c;該對象與MVC組建…

【數據結構】跳表

目錄 1.什么是跳表-skiplist 2.skiplist的效率如何保證&#xff1f; 3.skiplist的實現 3.1節點和成員設計 3.2查找實現 3.3前置節點查找 3.4插入實現 3.5刪除實現 3.6隨機層數 3.7完整代碼 4.skiplist跟平衡搜索樹和哈希表的對比 1.什么是跳表-skiplist skiplist是由…

html實現右上角有個圖標,鼠標移動到該位置出現手型,點擊會彈出登錄窗口。

寫了一段html代碼實現的效果&#xff1a;實現右上角有個圖標&#xff0c;鼠標移動到該位置出現手型&#xff0c;點擊會彈出登錄窗口。功能實現前端&#xff0c;沒有實現后端。<!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF…

STM32G4 電流環閉環(二) 霍爾有感運行

目錄一、STM32G4 電流環閉環(二) 霍爾有感運行2. 霍爾有感運行附學習參考網址歡迎大家有問題評論交流 (* ^ ω ^)一、STM32G4 電流環閉環(二) 霍爾有感運行 2. 霍爾有感運行 文章使用的BLDC在定子側以互差120電角度的位置安裝三個霍爾元件Ha&#xff0c;Hb&#xff0c;Hc。當…

展示框選擇

好的&#xff0c;非常感謝您提供更詳細的項目情況。這是一個非常典型的父子組件通信場景。 根據您的新需求&#xff0c;我將對代碼進行重構&#xff1a; FaultSelect.vue (子組件): 這個組件現在將變得更加“純粹”。它只負責自身的下拉框邏輯&#xff0c;不關心外部按鈕&#…

第5課:上下文管理與狀態持久化

第5課:上下文管理與狀態持久化 課程目標 掌握上下文存儲和檢索策略 學習會話狀態管理 了解數據持久化方案 實踐實現上下文管理系統 課程內容 5.1 上下文管理基礎 什么是上下文管理? 上下文管理是Agent系統中維護和利用歷史信息的能力,包括: 對話歷史:用戶與Agent的交互…

計算機畢業設計 基于大數據技術的醫療數據分析與研究 Python 大數據畢業設計 Hadoop畢業設計選題【附源碼+文檔報告+安裝調試】

博主介紹&#xff1a;?從事軟件開發10年之余&#xff0c;專注于Java技術領域、Python、大數據、人工智能及數據挖掘、小程序項目開發和Android項目開發等。CSDN、掘金、華為云、InfoQ、阿里云等平臺優質作者? &#x1f345;文末獲取源碼聯系&#x1f345; &#x1f447;&…

K8S集群管理(2)

目錄 1.什么是Pod的根容器&#xff1f; 2.解釋Pod的生命周期。 3.Init類型容器有什么特點&#xff0c;主要用途&#xff1f; 4.Sidecar類型容器和Init容器的區別在哪&#xff1f; 5.什么是靜態Pod&#xff1f; 6.說明K8s控制器的作用&#xff1f; 7.什么是ReplicaSet&#xff0…

視頻全模態referring分割:Ref-AVS: Refer and Segment Objects in Audio-Visual Scenes

一、TL&#xff1b;DR 為什么要做&#xff1a;傳統的referring分割無法使用音頻模態&#xff0c;本文提出Reference audio-visual Segmentation本文怎么做&#xff1a;構建首個 Ref-AVS 基準數據集通過充分利用多模態提示&#xff0c;將音頻信息通過和文本融合作為載體&#x…

A股大盤數據-20250916分析

&#x1f4ca; 一、大盤數據深度分析1.1 &#x1f9ee; 市場活躍度與資金流向總成交額&#xff1a;滬深京合計約 2.37萬億元&#xff0c;市場交投活躍&#xff0c;深市成交&#xff08;13516.4億&#xff09;明顯高于滬市&#xff08;9897.9億&#xff09;&#xff0c;顯示中小…

[計算機畢業設計]基于深度學習的噪聲過濾音頻優化系統研究

前言 &#x1f4c5;大四是整個大學期間最忙碌的時光,一邊要忙著備考或實習為畢業后面臨的就業升學做準備,一邊要為畢業設計耗費大量精力。近幾年各個學校要求的畢設項目越來越難,有不少課題是研究生級別難度的,對本科同學來說是充滿挑戰。為幫助大家順利通過和節省時間與精力投…

貪心算法應用:NFV功能部署問題詳解

Java中的貪心算法應用&#xff1a;NFV功能部署問題詳解 1. NFV功能部署問題概述 網絡功能虛擬化(NFV, Network Function Virtualization)是一種將傳統網絡設備功能從專用硬件轉移到虛擬化軟件的技術。在NFV功能部署問題中&#xff0c;我們需要將各種虛擬網絡功能(VNFs)部署到有…

SeriLog測試

安裝Serilog.Sinks.Seq(5.2.3.0)&#xff0c;Serilog.Sinks.File(7.0.0) 下載Seq安裝包并安裝&#xff08;https://datalust.co/download&#xff09; 代碼如下&#xff1a; private Logger _logger;private void button1_Click(object sender, EventArgs e){_logger new Lo…

HarmonyOS 5.0應用開發——V2裝飾器@param的使用

【高心星出品】 文章目錄V2裝飾器param的使用概念使用方法案例V2裝飾器param的使用 概念 在鴻蒙ArkTS開發中&#xff0c;Param裝飾器是組件間狀態管理的重要工具&#xff0c;主要用于父子組件間的單向數據傳遞&#xff0c;這一點與V1中的prop類似。 Param裝飾的變量支持本地…

SLAM | 無人機視覺/激光雷達集群SLAM技術進展綜述

主要內容如下: 無人機集群SLAM技術概述:介紹無人機集群SLAM的基本概念、重要性及面臨的挑戰,使用表格對比不同傳感器配置的特點。 多傳感器融合與協同SLAM架構:分析集中式、分布式和混合式協同架構的特點,使用表格對比不同架構的優缺點。 視覺協同SLAM的技術進展:總結直接…