MyBatis(原 iBATIS)是優秀的持久層框架,支援自定義 SQL、存儲過程與高級映射,通過 XML 或註解將介面與 POJO 映射到數據庫記錄。本教程以 MySQL 為例,演示從零搭建到增刪改查全流程。
<dependencies>
<!-- MyBatis 核心 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.13</version>
</dependency>
<!-- MySQL 驅動 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.0.33</version>
</dependency>
<!-- 日誌(控制台輸出 SQL) -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>2.0.9</version>
</dependency>
</dependencies>
CREATE DATABASE mybatis_demo CHARACTER SET utf8mb4;
USE mybatis_demo;
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
age INT,
email VARCHAR(100),
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO users(name, age, email) VALUES
('孤獨蒼狼', 28, 'wolf@example.com'),
('白虎神皇', 32, 'tiger@example.com');
<?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>
<!-- 別名包,簡寫 POJO 全限定名 -->
<typeAliases>
<package name="com.example.entity"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis_demo?useSSL=false&serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!-- 映射器註冊 -->
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
</configuration>
package com.example.entity;
public class User {
private Integer id;
private String name;
private Integer age;
private String email;
private LocalDateTime createTime;
// Getter/Setter/toString 省略
}
package com.example.mapper;
import com.example.entity.User;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface UserMapper {
User selectById(@Param("id") Integer id);
List<User> selectAll();
int insert(User user);
int update(User user);
int deleteById(@Param("id") Integer id);
}
<?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="com.example.mapper.UserMapper">
<!-- 通用結果映射 -->
<resultMap id="userMap" type="User">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
<result property="email" column="email"/>
<result property="createTime" column="create_time"/>
</resultMap>
<select id="selectById" resultMap="userMap">
SELECT * FROM users WHERE id = #{id}
</select>
<select id="selectAll" resultMap="userMap">
SELECT * FROM users ORDER BY id
</select>
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
INSERT INTO users(name, age, email) VALUES(#{name}, #{age}, #{email})
</insert>
<update id="update">
UPDATE users SET name=#{name}, age=#{age}, email=#{email} WHERE id=#{id}
</update>
<delete id="deleteById">
DELETE FROM users WHERE id = #{id}
</delete>
</mapper>
package com.example.test;
import com.example.entity.User;
import com.example.mapper.UserMapper;
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 java.io.IOException;
import java.io.Reader;
import java.util.List;
public class MyBatisQuickStart {
public static void main(String[] args) throws IOException {
// 1. 加載配置
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
// 2. 開啟會話(自動提交 false,手動控制事務)
try (SqlSession session = factory.openSession(false)) {
UserMapper mapper = session.getMapper(UserMapper.class);
// 3. 查詢單條
User user = mapper.selectById(1);
System.out.println("查詢ID=1: " + user);
// 4. 查詢列表
List<User> users = mapper.selectAll();
System.out.println("總用戶數: " + users.size());
// 5. 新增(返回自增 ID)
User newUser = new User();
newUser.setName("測試用戶");
newUser.setAge(25);
newUser.setEmail("test@demo.com");
int insertRows = mapper.insert(newUser);
System.out.println("新增行數: " + insertRows + ", 生成ID: " + newUser.getId());
// 6. 修改
newUser.setAge(26);
int updateRows = mapper.update(newUser);
System.out.println("修改行數: " + updateRows);
// 7. 刪除
int deleteRows = mapper.deleteById(newUser.getId());
System.out.println("刪除行數: " + deleteRows);
// 8. 提交事務
session.commit();
}
}
}
| 概念 | 說明 | 關鍵配置 |
|---|---|---|
| SqlSessionFactory | 線程安全,項目單例,構建開銷大 | SqlSessionFactoryBuilder.build() |
| SqlSession | 非線程安全,請求級/事務級,用完必須 close | factory.openSession() |
| Mapper 接口 | 動態代理實現,無需寫實現類 | namespace = 接口全限定名 |
| 參數綁定 | #{param} 預編譯防注入,${param} 直接拼接(慎用) | @Param 註解多參數 |
| 主鍵回填 | useGeneratedKeys + keyProperty | MySQL 自增主鍵 |
<if>、<choose>、<where>、<trim>、<foreach><resultMap> 的 <association>(一對一)、<collection>(一對多)SqlSessionFactoryBean、MapperScannerConfigurer、聲明式事務MyBatis 以「SQL 為中心」設計哲學,保留了 SQL 的完全控制權,同時通過映射層消除 JDBC 樣板代碼。掌握 配置 → 實體 → 接口 → XML → 測試 五步走流程,即可快速上手生產開發。建議後續深入學習動態 SQL 與關聯映射,解決複雜查詢場景。