Hibernate、OJB 等完整 ORM 框架雖然強大,但學習曲線陡峭、SQL 控制權旁落。iBATIS(現更名為 MyBatis)採取不同哲學:不嘗試將物件映射到資料表,而是將 SQL 映射到物件。開發者保有完整 SQL 控制權,框架只負責「結果集 ↔ 物件」的繁瑣轉換工作。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "https://www.ibatis.com/dtd/sql-map-2.dtd">
<sqlMap namespace="Employee">
<!-- 結果映射:將查詢欄位對應到 Employee 物件屬性 -->
<resultMap id="employeeResult" class="com.example.model.Employee">
<result property="id" column="emp_id"/>
<result property="lastName" column="last_name"/>
<result property="firstName" column="first_name"/>
<result property="title" column="title"/>
</resultMap>
<!-- 查詢陳述式 -->
<select id="loadEmployee" resultMap="employeeResult" parameterClass="java.lang.Long">
SELECT emp_id, last_name, first_name, title
FROM employees
WHERE emp_id = #value#
</select>
<!-- 插入/更新/刪除同理 -->
<insert id="insertEmployee" parameterClass="com.example.model.Employee">
INSERT INTO employees (last_name, first_name, title)
VALUES (#lastName#, #firstName#, #title#)
</insert>
</sqlMap>
public class EmployeeDao {
private SqlMapClient sqlMap; // 由 SqlMapClientBuilder 建立
public Employee getEmployeeById(Long id) {
return (Employee) sqlMap.queryForObject("Employee.loadEmployee", id);
}
public void insertEmployee(Employee emp) {
sqlMap.insert("Employee.insertEmployee", emp);
}
}
| 優勢 | 注意事項 |
|---|---|
| 學習曲線平緩:懂 SQL 就懂 iBATIS | SQL 寫死在 XML,跨資料庫移植需維護多套映射檔 |
| 效能可預測:SQL 由 DBA 優化,無隱性 N+1 查詢問題 | 缺乏物件導向查詢語言(如 HQL),複雜動態查詢需靠 XML 標籤 |
| 支援預存程序、動態 SQL、延遲載入、快取等進階特性 | 物件關聯映射(一對多、多對多)需手工配置 <resultMap> 較繁瑣 |
| 輕量級:單一 JAR,零強制依賴 | 現代專案建議直接使用 MyBatis 3.x(註解支援、型別安全、Spring 整合更完善) |
<select id="findEmployees" resultMap="employeeResult" parameterClass="map">
SELECT * FROM employees
<where>
<isNotEmpty property="lastName">
AND last_name LIKE #lastName#
</isNotEmpty>
<isNotEmpty property="deptId">
AND dept_id = #deptId#
</isNotEmpty>
</where>
ORDER BY emp_id
</select>
com.ibatis.* → org.apache.ibatis.*<if>, <choose>, <bind> 等)。MapperScannerConfigurer 自動掃描註冊,極度簡化配置。iBATIS/MyBatis 的核心價值在於「SQL 即原始碼」。它不試圖隱藏 SQL,而是擁抱 SQL,讓開發者專注於領域模型與資料存取邏輯的乾淨分離。