MyBatis(前身 iBatis)是一款優秀的半自動 ORM 持久層框架,支持自定義 SQL、存儲過程與高級映射。本文系統梳理其發展歷程、與 Hibernate 差異、三層架構設計,並通過完整 XML 配置示例帶你跑通第一個查詢。

| 層級 | 名稱 | 職責 |
|---|---|---|
| 1 | API 接口層 | 對外暴露 SqlSession 等接口,開發者調用增刪改查方法,內部委託數據處理層 |
| 2 | 數據處理層 | 核心邏輯:SQL 查找、解析(動態標籤)、執行、結果映射(ResultMap/TypeHandler) |
| 3 | 基礎支撐層 | 連接池、事務管理、配置加載、緩存(一級/二級),為上層提供基礎設施 |
入口類,負責解析 mybatis-config.xml 生成 Configuration 對象,構建 SqlSessionFactory。線程安全,應用全局單例。
String resource = "mybatis-config.xml"; Reader reader = Resources.getResourceAsReader(resource); SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); SqlSessionFactory factory = builder.build(reader);
工廠接口,創建 SqlSession。同樣全局單例。持有 Configuration 全局配置。
非線程安全,對應一次數據庫會話,提供 CRUD 方法、事務控制、獲取 Mapper 接口代理。用完必須 close()。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 類型別名,簡化 Mapper XML 中的 resultType/typeAlias -->
<typeAliases>
<typeAlias type="org.example.dao.UserDao" alias="UserDao"/>
<typeAlias type="org.example.dto.UserDto" alias="UserDto"/>
</typeAliases>
<!-- 環境配置:事務管理器 + 數據源 -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!-- 映射器註冊 -->
<mappers>
<mapper resource="org/example/dao/UserDao.xml"/>
<!-- 掃描包下所有 Mapper -->
<!-- <package name="org.example.dao"/> -->
</mappers>
</configuration>
XML 头部 DOCTYPE 聲明必須保留,用於 DTD 驗證。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.example.dao.UserDao">
<resultMap id="userMap" type="UserDto">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="email" column="email"/>
</resultMap>
<select id="selectById" parameterType="int" resultMap="userMap">
SELECT id, name, email FROM t_user WHERE id = #{id}
</select>
<insert id="insert" parameterType="UserDto" useGeneratedKeys="true" keyProperty="id">
INSERT INTO t_user(name, email) VALUES(#{name}, #{email})
</insert>
</mapper>
package org.example.dao;
import org.example.dto.UserDto;
import java.util.List;
public interface UserDao {
UserDto selectById(int id);
List<UserDto> selectAll();
int insert(UserDto user);
}
public class MyBatisQuickStart {
private static SqlSessionFactory sqlSessionFactory;
@BeforeClass
public static void init() throws IOException {
String resource = "mybatis-config.xml";
Reader reader = Resources.getResourceAsReader(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
}
@Test
public void testSelectById() {
try (SqlSession session = sqlSessionFactory.openSession()) {
UserDao dao = session.getMapper(UserDao.class);
UserDto user = dao.selectById(1);
System.out.println(user);
}
}
}
<where>, <if>, <choose>, <foreach> 構建靈活查詢<cache/> 並實現序列化MapperScannerConfigurer 自動掃描 Mapper 接口生成代理 Bean,SqlSessionFactoryBean 管理工廠MyBatis 以「SQL 為中心」設計,給予開發者完全的 SQL 掌控權,配合強大的結果映射與動態 SQL 能力,成為 Java 持久層主流選擇之一。掌握 SqlSessionFactoryBuilder → SqlSessionFactory → SqlSession → Mapper 調用鏈路,是入門的關鍵。