🔍 MyBatis 與 MyBatis-Plus 的對比與選擇
文章目錄
- 🔍 MyBatis 與 MyBatis-Plus 的對比與選擇
- 🧠 一、MyBatis 核心回顧
- 💡 核心思想與架構定位
- ? 基礎使用示例
- ?? MyBatis 的痛點
- ? 二、MyBatis-Plus 功能特性解析
- 💡 MyBatis-Plus 定位
- 🚀 1. 單表 CRUD 封裝
- 🔧 2. 條件構造器(Wrapper)
- 🛠? 3. 插件體系
- 🚀 三、代碼生成與快速開發
- 💡 代碼生成器配置
- ? 生成結果結構
- ?? 四、全方位對比分析
- 💡 核心特性對比
- 📊 性能對比
- 🔧 代碼量對比
- 🎯 五、適用場景與選型指南
- 💡 技術選型決策框架
- 🎯 具體場景建議
- 📝 選型檢查清單
- 🔧 六、混合使用策略
- 💡 共存與漸進式遷移
- ? 混合使用示例
- 🔧 遷移策略建議
- 🔚 總結與建議
- 📚 核心結論
- 🎯 最終建議
🧠 一、MyBatis 核心回顧
💡 核心思想與架構定位
MyBatis 作為半自動化的 ORM 框架,其設計哲學是:
MyBatis 的核心價值??:
- 🎯 ??SQL可控性??:開發者完全掌握SQL優化
- 🔧 ??靈活性??:支持復雜查詢和存儲過程
- 📊 ??映射簡單??:ResultMap實現對象關系映射
- 🛡? ??穩定性??:經過大量生產環境驗證
? 基礎使用示例
// 傳統MyBatis的Mapper接口
public interface UserMapper {@Select("SELECT * FROM users WHERE id = #{id}")User selectById(Integer id);@Insert("INSERT INTO users(name, email) VALUES(#{name}, #{email})")@Options(useGeneratedKeys = true, keyProperty = "id")int insert(User user);@Update("UPDATE users SET name=#{name} WHERE id=#{id}")int update(User user);@Delete("DELETE FROM users WHERE id = #{id}")int delete(Integer id);
}
XML 映射文件??:
<!-- UserMapper.xml -->
<mapper namespace="com.example.mapper.UserMapper"><select id="selectByCondition" resultType="User">SELECT * FROM usersWHERE status = #{status}<if test="name != null">AND name LIKE CONCAT('%', #{name}, '%')</if>ORDER BY id DESC</select>
</mapper>
?? MyBatis 的痛點
痛點 | 描述 | 影響 |
---|---|---|
重復CRUD | 每個實體都需要基礎CRUD方法 | 開發效率低 |
SQL編寫 | 簡單查詢也需要手動編寫SQL | 代碼冗余 |
分頁復雜 | 需要插件或手動實現分頁 | 一致性差 |
代碼生成 | 缺乏官方代碼生成工具 | 初期搭建繁瑣 |
? 二、MyBatis-Plus 功能特性解析
💡 MyBatis-Plus 定位
MyBatis-Plus 是 MyBatis 的增強工具,在保留 MyBatis 所有特性的基礎上,提供了更便捷的開發體驗:
🚀 1. 單表 CRUD 封裝
??Mapper 接口繼承??:
// 只需繼承BaseMapper即可獲得完整CRUD能力
public interface UserMapper extends BaseMapper<User> {// 無需編寫基礎CRUD方法// 自定義復雜查詢方法List<User> selectComplexQuery(UserQuery query);
}// 服務層使用
@Service
public class UserService {@Autowiredprivate UserMapper userMapper;public void addUser(User user) {// 直接使用MyBatis-Plus提供的方法int result = userMapper.insert(user);}public User getUserById(Long id) {return userMapper.selectById(id);}public List<User> getUsersByCondition() {// 使用QueryWrapper構建查詢條件QueryWrapper<User> wrapper = new QueryWrapper<>();wrapper.eq("status", 1).like("name", "張").orderByDesc("create_time");return userMapper.selectList(wrapper);}
}
🔧 2. 條件構造器(Wrapper)
??Lambda 表達式條件構造??:
// Lambda條件構造器(推薦)
public List<User> getActiveUsers(String keyword) {LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery();wrapper.eq(User::getStatus, 1).like(StringUtils.isNotBlank(keyword), User::getName, keyword).between(User::getCreateTime, startDate, endDate).orderByDesc(User::getCreateTime);return userMapper.selectList(wrapper);
}// 更新操作條件構造
public int updateUserStatus(Long userId, Integer status) {User user = new User();user.setStatus(status);UpdateWrapper<User> wrapper = new UpdateWrapper<>();wrapper.eq("id", userId).eq("status", 0); // 只更新狀態為0的用戶return userMapper.update(user, wrapper);
}
🛠? 3. 插件體系
??常用插件配置??:
@Configuration
public class MybatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();// 分頁插件PaginationInnerInterceptor paginationInterceptor = new PaginationInnerInterceptor();paginationInterceptor.setDbType(DbType.MYSQL);paginationInterceptor.setMaxLimit(1000L); // 單頁最大條數interceptor.addInnerInterceptor(paginationInterceptor);// 樂觀鎖插件OptimisticLockerInnerInterceptor optimisticLockerInterceptor = new OptimisticLockerInnerInterceptor();interceptor.addInnerInterceptor(optimisticLockerInterceptor);return interceptor;}
}
??分頁查詢示例??:
public Page<User> getUsersByPage(int pageNum, int pageSize, UserQuery query) {Page<User> page = new Page<>(pageNum, pageSize);LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery();wrapper.eq(query.getStatus() != null, User::getStatus, query.getStatus()).like(StringUtils.isNotBlank(query.getKeyword()), User::getName, query.getKeyword());return userMapper.selectPage(page, wrapper);
}
🚀 三、代碼生成與快速開發
💡 代碼生成器配置
public class CodeGenerator {public static void main(String[] args) {AutoGenerator generator = new AutoGenerator();// 數據源配置DataSourceConfig dataSourceConfig = new DataSourceConfig();dataSourceConfig.setUrl("jdbc:mysql://localhost:3306/test");dataSourceConfig.setUsername("root");dataSourceConfig.setPassword("123456");dataSourceConfig.setDriverName("com.mysql.cj.jdbc.Driver");generator.setDataSource(dataSourceConfig);// 全局配置GlobalConfig globalConfig = new GlobalConfig();globalConfig.setOutputDir(System.getProperty("user.dir") + "/src/main/java");globalConfig.setAuthor("Developer");globalConfig.setOpen(false);globalConfig.setSwagger2(true);generator.setGlobalConfig(globalConfig);// 包配置PackageConfig packageConfig = new PackageConfig();packageConfig.setParent("com.example");packageConfig.setEntity("entity");packageConfig.setMapper("mapper");packageConfig.setService("service");packageConfig.setController("controller");generator.setPackageInfo(packageConfig);// 策略配置StrategyConfig strategyConfig = new StrategyConfig();strategyConfig.setNaming(NamingStrategy.underline_to_camel);strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);strategyConfig.setEntityLombokModel(true);strategyConfig.setRestControllerStyle(true);strategyConfig.setInclude("user", "order"); // 要生成的表generator.setStrategy(strategyConfig);generator.execute();}
}
? 生成結果結構
src/main/java/com/example/
├── entity/ # 實體類
│ ├── User.java
│ └── Order.java
├── mapper/ # Mapper接口
│ ├── UserMapper.java
│ └── OrderMapper.java
├── service/ # 服務接口
│ ├── IUserService.java
│ └── IOrderService.java
└── controller/ # 控制器├── UserController.java└── OrderController.java
?? 四、全方位對比分析
💡 核心特性對比
特性 | MyBatis | MyBatis-Plus | 優勢方 |
---|---|---|---|
CRUD操作 | 手動編寫 | 自動封裝 | MyBatis-Plus |
條件構造 | 手動拼接 | Lambda表達式 | MyBatis-Plus |
代碼生成 | 需要插件 | 官方生成器 | MyBatis-Plus |
SQL控制 | 完全控制 | 部分封裝 | MyBatis |
學習曲線 | 平緩 | 稍陡峭 | MyBatis |
靈活性 | 高 | 中等 | MyBatis |
開發效率 | 低 | 高 | MyBatis-Plus |
社區生態 | 成熟穩定 | 活躍發展 | 持平 |
📊 性能對比
場景 | MyBatis | MyBatis-Plus | 說明 |
---|---|---|---|
簡單CRUD | 100ms | 95ms | 差異不大 |
復雜查詢 | 150ms | 160ms | MyBatis略優 |
分頁查詢 | 依賴插件 | 原生支持 | MyBatis-Plus更穩定 |
批量操作 | 需要手動實現 | 內置支持 | MyBatis-Plus更便捷 |
🔧 代碼量對比
??相同功能的實現代碼量??:
// MyBatis實現分頁查詢
public List<User> getUsersByPage(int pageNum, int pageSize, String keyword) {RowBounds rowBounds = new RowBounds((pageNum - 1) * pageSize, pageSize);return userMapper.selectUsersByKeyword(keyword, rowBounds);
}// MyBatis-Plus實現分頁查詢
public Page<User> getUsersByPage(int pageNum, int pageSize, String keyword) {Page<User> page = new Page<>(pageNum, pageSize);LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery();wrapper.like(StringUtils.isNotBlank(keyword), User::getName, keyword);return userMapper.selectPage(page, wrapper);
}
🎯 五、適用場景與選型指南
💡 技術選型決策框架
🎯 具體場景建議
??推薦使用 MyBatis-Plus 的場景??:
- ??新項目啟動??:快速搭建基礎CRUD功能
- 管理后臺系統??:大量表單和列表頁面 ??
- 微服務架構??:需要快速開發數據訪問層
- 團隊技能一般??:團隊成員SQL能力較弱
??推薦使用 MyBatis 的場景??:
- 復雜業務系統??:需要復雜SQL和存儲過程 ??
- 性能敏感場景??:需要精細控制SQL優化
- ??遺留系統維護??:基于MyBatis的現有系統
- DBA嚴格管控??:SQL需要DBA審核的場景
📝 選型檢查清單
考慮因素 | MyBatis | MyBatis-Plus |
---|---|---|
開發速度要求 | ? | ? |
SQL復雜度要求 | ? | ? |
團隊學習成本 | ? | ? |
長期維護性 | ? | ? |
生態完整性 | ? | ? |
性能要求 | ? | ?? |
🔧 六、混合使用策略
💡 共存與漸進式遷移
在實際項目中,可以采用混合使用策略:
? 混合使用示例
// 傳統MyBatis的Mapper
public interface UserMapper extends BaseMapper<User> {// MyBatis-Plus提供的CRUD方法// 自定義復雜查詢(傳統MyBatis方式)@Select("SELECT * FROM users WHERE create_time BETWEEN #{start} AND #{end}")List<User> selectByCreateTimeRange(@Param("start") Date start, @Param("end") Date end);// 使用MyBatis-Plus的條件構造器default List<User> selectByComplexCondition(UserQuery query) {LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery();wrapper.eq(query.getStatus() != null, User::getStatus, query.getStatus()).ge(query.getStartTime() != null, User::getCreateTime, query.getStartTime()).le(query.getEndTime() != null, User::getCreateTime, query.getEndTime());return selectList(wrapper);}
}
🔧 遷移策略建議
- ??初期??:新功能使用 MyBatis-Plus,舊功能保持不動 ??
- 中期??:逐步將簡單CRUD遷移到 MyBatis-Plus
- 后期??:復雜功能評估后決定是否遷移
🔚 總結與建議
📚 核心結論
- ??MyBatis??:適合需要精細控制SQL、復雜查詢場景
- ??MyBatis-Plus??:適合快速開發、簡單CRUD為主的項目
- 混合使用??:大多數現實項目的合理選擇
🎯 最終建議
項目類型 | 推薦方案 | 理由 |
---|---|---|
全新項目 | MyBatis-Plus | 開發效率高,功能全面 |
復雜系統 | MyBatis | SQL控制精細,性能優化空間大 |
遷移項目 | 混合策略 | 平衡效率與風險 |
微服務 | MyBatis-Plus | 快速迭代,標準統一 |