在 Java 后端開發中,JdbcTemplate(Spring 框架提供)和 MyBatis(持久層框架)都是用于簡化數據庫操作的工具,但它們的設計理念、使用方式、靈活性和適用場景有顯著差異。下面從核心定位、核心特性、使用方式、優缺點等維度進行全面對比
一、核心定位與設計理念
對比維度 | JdbcTemplate | MyBatis |
---|---|---|
所屬框架 | Spring 框架內置(spring-jdbc 模塊) | 獨立的持久層框架(可與 Spring 整合) |
設計核心 | 封裝 JDBC 細節,簡化“模板化”SQL操作 | 專注于 SQL 與 Java 代碼的解耦,支持 SQL 靈活定制 |
定位 | “輕量級 JDBC 工具”,無 ORM 特性 | “半自動化 ORM 框架”(需手動寫 SQL,自動映射結果) |
核心目標 | 減少 JDBC 重復代碼(如連接管理、異常處理) | 平衡 SQL 靈活性與代碼簡潔性,避免硬編碼 SQL |
二、核心特性對比
特性 | JdbcTemplate | MyBatis |
---|---|---|
SQL 編寫位置 | 硬編碼在 Java 代碼中(字符串形式) | 寫在 XML 映射文件或 Java 注解中 |
參數映射 | 手動通過 ? 占位符傳參(如 update("SELECT * FROM user WHERE id = ?", 1) ) | 支持 #{}(預編譯,防注入) 和 ${}(字符串拼接) ,自動映射 Java 對象參數 |
結果集映射 | 需手動處理 ResultSet (如用 RowMapper 轉 Java 對象) | 自動映射(SQL 列名與 Java 對象屬性名匹配,支持自定義映射規則) |
動態 SQL | 無原生支持,需手動用字符串拼接(易出錯、有注入風險) | 原生支持動態 SQL(<if> 、<foreach> 、<choose> 等標簽),安全且靈活 |
緩存支持 | 無內置緩存,需依賴 Spring 緩存(如 @Cacheable ) | 內置一級緩存(SqlSession 級別)和二級緩存(Mapper 級別),支持整合第三方緩存(如 Redis) |
批量操作 | 支持但需手動調用 batchUpdate() ,代碼較繁瑣 | 支持 BatchExecutor ,配合 <foreach> 可簡化批量插入/更新 |
存儲過程調用 | 需手動處理 CallableStatement ,代碼復雜 | 原生支持存儲過程(<select statementType="CALLABLE"> ) |
XML 配置 | 無需額外 XML,依賴 Spring 配置文件(如數據源) | 需配置核心配置文件(mybatis-config.xml )和映射文件(XxxMapper.xml ) |
代碼侵入性 | 高(SQL 與 Java 代碼耦合) | 低(SQL 與 Java 代碼分離) |
三、使用方式示例(以“查詢用戶”為例)
通過具體代碼對比,更直觀理解兩者差異。
1. JdbcTemplate 實現
需先在 Spring 配置數據源(如 application.yml
),再注入 JdbcTemplate
:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import com.example.admin.entity.User;@Repository
public class UserDao {// 注入 Spring 自動配置的 JdbcTemplate@Autowiredprivate JdbcTemplate jdbcTemplate;// 查詢單個用戶public User getUserById(Long id) {// 1. SQL 硬編碼在代碼中String sql = "SELECT id, username, email FROM user WHERE id = ?";// 2. 手動用 RowMapper 映射 ResultSet 到 User 對象RowMapper<User> rowMapper = (rs, rowNum) -> {User user = new User();user.setId(rs.getLong("id"));user.setUsername(rs.getString("username"));user.setEmail(rs.getString("email"));return user;};// 3. 執行查詢并返回結果return jdbcTemplate.queryForObject(sql, rowMapper, id);}
}
2. MyBatis 實現
分 3 步:定義 Mapper 接口、編寫 XML 映射文件、配置 MyBatis(Spring Boot 中可自動配置)。
步驟 1:定義 Mapper 接口(無實現類)
import org.apache.ibatis.annotations.Mapper;
import com.example.admin.entity.User;@Mapper // 標記為 MyBatis Mapper 接口,Spring 自動掃描
public interface UserMapper {// 方法名與 XML 中 SQL 的 id 對應User getUserById(Long id);
}
步驟 2:編寫 XML 映射文件(UserMapper.xml
)
放在 resources/mapper
目錄下,SQL 與代碼分離:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"><!-- namespace 對應 Mapper 接口全路徑 -->
<mapper namespace="com.example.admin.mapper.UserMapper"><!-- id 對應接口方法名,resultType 指定返回值類型(自動映射) --><select id="getUserById" resultType="com.example.admin.entity.User">SELECT id, username, email FROM user WHERE id = #{id}<!-- #{id} 自動接收參數,預編譯防 SQL 注入 --></select>
</mapper>
步驟 3:Service 層調用 Mapper
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.admin.entity.User;
import com.example.admin.mapper.UserMapper;@Service
public class UserService {@Autowiredprivate UserMapper userMapper; // 注入 Mapper 接口(MyBatis 動態代理生成實現類)public User getUserById(Long id) {return userMapper.getUserById(id); // 直接調用接口方法}
}
四、優缺點對比
框架 | 優點 | 缺點 |
---|---|---|
JdbcTemplate | 1. 輕量級,無額外依賴(僅依賴 Spring) 2. 學習成本低,上手快 3. 代碼簡潔(適合簡單 SQL 操作) 4. 靈活控制 JDBC 細節(如自定義 ResultSet 處理) | 1. SQL 硬編碼,維護困難(復雜項目中代碼混亂) 2. 無動態 SQL 支持,拼接 SQL 易出錯 3. 無自動映射,需手動寫 RowMapper 4. 不支持緩存,批量操作繁瑣 |
MyBatis | 1. SQL 與代碼分離,維護性好 2. 原生動態 SQL,支持復雜查詢 3. 自動參數/結果映射,減少重復代碼 4. 內置緩存,提升性能 5. 支持存儲過程、批量操作 | 1. 需額外學習 MyBatis 語法(XML 標簽、配置規則) 2. 復雜業務(多表關聯)需手動寫 SQL,工作量大 3. 無完全自動化 ORM(對比 Hibernate) |
五、選型建議
根據項目規模、SQL 復雜度、團隊技術棧選擇:
場景 | 推薦框架 | 理由 |
---|---|---|
小型項目/工具類(如你之前的“在線工具集管理后臺”初期) | JdbcTemplate | 需求簡單,SQL 不復雜,無需額外學習成本,快速開發 |
中大型項目(多表關聯、動態 SQL 多) | MyBatis | SQL 靈活定制,維護性好,支持動態 SQL 和緩存,適合復雜業務場景 |
團隊不熟悉 MyBatis,更熟悉 Spring | JdbcTemplate | 降低學習成本,利用現有 Spring 技術棧 |
需頻繁調整 SQL(如報表統計、復雜查詢) | MyBatis | SQL 獨立存儲,修改無需重新編譯代碼,迭代效率高 |
簡單 CRUD 操作占比高 | 可結合 MyBatis-Plus | MyBatis-Plus 是 MyBatis 的增強工具,提供“無 SQL CRUD”(如 baseMapper.insert(user) ),兼顧靈活性和效率 |
六、補充:MyBatis-Plus 簡介
如果你使用 MyBatis,推薦搭配 MyBatis-Plus(簡稱 MP),它是 MyBatis 的“增強工具”,不改變 MyBatis 核心邏輯,卻能大幅減少重復 CRUD 代碼:
- 提供
BaseMapper
接口,內置insert
/deleteById
/updateById
/selectList
等方法,無需寫 XML; - 支持 Lambda 表達式查詢(如
query().eq(User::getId, 1).one()
); - 原生支持分頁、批量操作、邏輯刪除等功能。