MyBatis?和?MyBatis-Plus從語法詳解和優(yōu)劣對比
MyBatis 和 MyBatis-Plus 是 Java 生態(tài)中常用的持久層框架,其中 MyBatis-Plus 是在 MyBatis 基礎(chǔ)上的增強工具(“只做增強,不做改變”)。下面從語法詳解和優(yōu)劣對比兩部分展開說明。
一、MyBatis 語法詳解
MyBatis 的核心是 “SQL 映射”,通過 XML 或注解將 Java 方法與 SQL 語句綁定,需手動定義 SQL 邏輯。其語法圍繞 “配置文件 + Mapper 接口 + SQL 映射(XML / 注解)” 展開。
1. 核心配置文件(mybatis-config.xml)
用于全局配置 MyBatis,包括數(shù)據(jù)源、別名、插件、映射器等,示例如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 1. 環(huán)境配置(數(shù)據(jù)源) -->
<environments default="dev">
<environment id="dev">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!-- 2. 別名配置(簡化類名引用) -->
<typeAliases>
<package name="com.example.entity"/> <!-- 掃描包,別名默認(rèn)為類名(首字母小寫) -->
</typeAliases>
<!-- 3. 映射器(關(guān)聯(lián)Mapper接口與SQL映射文件) -->
<mappers>
<package name="com.example.mapper"/> <!-- 掃描Mapper接口所在包 -->
</mappers>
</configuration>2. Mapper 接口
定義數(shù)據(jù)操作方法,需與 SQL 映射(XML / 注解)綁定,示例如下:
public interface UserMapper {
// 根據(jù)ID查詢用戶
User selectById(Long id);
// 新增用戶
int insert(User user);
// 批量刪除用戶
int deleteBatch(@Param("ids") List<Long> ids);
}3. SQL 映射(XML 方式,核心)
通過 XML 標(biāo)簽定義 SQL,支持動態(tài) SQL(MyBatis 一大特色),示例如下(UserMapper.xml):
<?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.mapper.UserMapper">
<!-- 1. 基礎(chǔ)查詢:根據(jù)ID查用戶 -->
<select id="selectById" resultType="User"> <!-- id對應(yīng)接口方法名,resultType對應(yīng)返回類型(別名) -->
SELECT id, username, age, create_time FROM user WHERE id = #{id} <!-- #{id}是參數(shù)占位符(預(yù)編譯,防SQL注入) -->
</select>
<!-- 2. 新增用戶 -->
<insert id="insert" parameterType="User"> <!-- parameterType是參數(shù)類型 -->
INSERT INTO user(username, age, create_time)
VALUES(#{username}, #{age}, #{createTime}) <!-- #{屬性名}對應(yīng)實體類字段(需與數(shù)據(jù)庫字段映射) -->
</insert>
<!-- 3. 動態(tài)SQL:批量刪除(if+foreach) -->
<delete id="deleteBatch">
DELETE FROM user
<where> <!-- where標(biāo)簽自動處理多余的AND/OR -->
<if test="ids != null and ids.size() > 0"> <!-- if標(biāo)簽:條件判斷(test里是OGNL表達(dá)式) -->
id IN
<foreach collection="ids" item="id" open="(" close=")" separator=","> <!-- foreach遍歷集合 -->
#{id}
</foreach>
</if>
</where>
</delete>
<!-- 4. 動態(tài)SQL:復(fù)雜查詢(choose/when/otherwise) -->
<select id="selectByCondition" resultType="User">
SELECT * FROM user
<where>
<choose> <!-- choose類似Java的switch:只執(zhí)行第一個滿足條件的when -->
<when test="username != null">username LIKE CONCAT('%', #{username}, '%')</when>
<when test="age != null">age = #{age}</when>
<otherwise>1=1</otherwise> <!-- 默認(rèn)條件(避免where后無內(nèi)容) -->
</choose>
</where>
</select>
</mapper>4. SQL 映射(注解方式,適合簡單 SQL)
直接在 Mapper 接口方法上用注解定義 SQL,無需 XML,示例如下:
public interface UserMapper {
@Select("SELECT id, username FROM user WHERE id = #{id}")
User selectById(Long id);
@Insert("INSERT INTO user(username, age) VALUES(#{username}, #{age})")
int insert(User user);
}二、MyBatis-Plus 語法詳解
MyBatis-Plus(簡稱 “MP”)基于 MyBatis 開發(fā),核心是 “增強 CRUD”—— 通過繼承接口、條件構(gòu)造器等簡化開發(fā),無需手動寫基本 SQL,同時兼容 MyBatis 語法(可混合使用)。
1. 核心依賴與配置
需引入 MyBatis-Plus 依賴(需排除 MyBatis 重復(fù)依賴),配置與 MyBatis 類似,僅需新增 MP 專屬插件(如分頁插件),示例如下(Spring Boot 環(huán)境):
@Configuration
@MapperScan("com.example.mapper") // 掃描Mapper接口
public class MyBatisPlusConfig {
// 分頁插件(MP提供,開箱即用)
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 適配MySQL
return interceptor;
}
}2. 核心接口:BaseMapper<T>(簡化 CRUD)
MP 提供 BaseMapper<T> 接口,內(nèi)置常用 CRUD 方法,自定義 Mapper 只需繼承它即可,無需手動寫 SQL。
示例:
// 實體類(需與數(shù)據(jù)庫表映射,用MP注解)
@Data
@TableName("user") // 指定數(shù)據(jù)庫表名(默認(rèn)類名小寫)
public class User {
@TableId(type = IdType.AUTO) // 主鍵策略(自增)
private Long id;
private String username;
private Integer age;
@TableField("create_time") // 映射數(shù)據(jù)庫字段(若屬性名與字段名一致可省略)
private LocalDateTime createTime;
}
// Mapper接口:繼承BaseMapper<T>,無需寫方法
public interface UserMapper extends BaseMapper<User> {
// 已繼承BaseMapper的20+個方法:insert、selectById、updateById、deleteById、selectList等
}直接調(diào)用繼承的方法(Service 層示例):
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public void testCRUD() {
// 1. 新增
User user = new User();
user.setUsername("mp-test");
user.setAge(20);
userMapper.insert(user); // 直接調(diào)用BaseMapper的insert方法
// 2. 根據(jù)ID查詢
User user = userMapper.selectById(1L);
// 3. 更新(根據(jù)ID)
user.setAge(21);
userMapper.updateById(user); // 僅更新非null字段
// 4. 刪除(根據(jù)ID)
userMapper.deleteById(1L);
// 5. 查詢所有
List<User> users = userMapper.selectList(null); // 參數(shù)為條件構(gòu)造器,null表示無條件
}
}3. 條件構(gòu)造器:QueryWrapper/UpdateWrapper(動態(tài) SQL 簡化)
MP 提供 QueryWrapper(查詢條件)和 UpdateWrapper(更新條件),通過鏈?zhǔn)椒椒▌討B(tài)構(gòu)建條件,無需寫 XML 動態(tài) SQL 標(biāo)簽。
示例 1:QueryWrapper(查詢條件)
public List<User> selectByCondition() {
// 構(gòu)建查詢條件:查詢年齡>20、用戶名含"張"、且創(chuàng)建時間在2023年后的用戶
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper
.gt("age", 20) // gt:大于(字段名用數(shù)據(jù)庫列名,或?qū)嶓w類屬性名)
.like("username", "張") // like:模糊查詢(默認(rèn)%值%)
.ge("create_time", LocalDateTime.of(2023, 1, 1, 0, 0, 0)) // ge:大于等于
.orderByDesc("create_time"); // 排序:按創(chuàng)建時間降序
// 調(diào)用selectList,傳入條件構(gòu)造器
return userMapper.selectList(queryWrapper);
}示例 2:UpdateWrapper(更新條件)
public void updateByCondition() {
// 構(gòu)建更新條件:將年齡<18的用戶的username改為"未成年"
UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
updateWrapper
.lt("age", 18) // lt:小于(條件)
.set("username", "未成年"); // set:更新的字段及值
// 調(diào)用update,傳入null(無需實體類)和條件構(gòu)造器
userMapper.update(null, updateWrapper);
}4. 分頁查詢(開箱即用)
MP 分頁插件配置后,直接用 IPage 接口即可實現(xiàn)分頁,無需手動寫 LIMIT 語句:
public IPage<User> selectPage(int pageNum, int pageSize) {
// 1. 創(chuàng)建分頁對象(pageNum:頁碼,pageSize:每頁條數(shù))
IPage<User> page = new Page<>(pageNum, pageSize);
// 2. 調(diào)用selectPage方法(BaseMapper提供),傳入分頁對象和條件構(gòu)造器(null表示查所有)
return userMapper.selectPage(page, null);
// 返回結(jié)果包含:總條數(shù)(total)、總頁數(shù)(pages)、當(dāng)前頁數(shù)據(jù)(records)等
}5. 其他增強功能(語法涉及注解 / 配置)
邏輯刪除:通過 @TableLogic 注解標(biāo)記邏輯刪除字段(如 deleted),刪除時自動改為 “更新 deleted=1”,查詢時自動過濾 deleted=0:
@TableLogic // 標(biāo)記邏輯刪除字段 private Integer deleted;
自動填充:通過 @TableField(fill = ...) 標(biāo)記需自動填充的字段(如 createTime),配合 MetaObjectHandler 實現(xiàn)新增 / 更新時自動賦值:
@TableField(fill = FieldFill.INSERT) // 新增時自動填充
private LocalDateTime createTime;
// 自定義填充處理器
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
}
}代碼生成器:通過 AutoGenerator 自動生成 Entity、Mapper、Service、Controller 等代碼,減少重復(fù)工作:
public class CodeGenerator {
public static void main(String[] args) {
AutoGenerator generator = new AutoGenerator();
// 配置數(shù)據(jù)源、包名、策略等(略)
generator.execute(); // 執(zhí)行生成
}
}三、MyBatis 與 MyBatis-Plus 的優(yōu)劣對比
兩者核心差異在于 “開發(fā)效率” 與 “靈活性” 的權(quán)衡,具體對比如下:
1. MyBatis 的優(yōu)劣
優(yōu)勢:
- 靈活性極高:開發(fā)者可完全控制 SQL 語句,支持復(fù)雜查詢(如多表聯(lián)查、子查詢、自定義函數(shù)等),適合業(yè)務(wù)邏輯復(fù)雜的場景(如金融、電商核心業(yè)務(wù))。
- SQL 優(yōu)化可控:可直接通過調(diào)整 SQL 語句優(yōu)化性能(如索引利用、查詢字段精簡),對底層 SQL 透明。
- 學(xué)習(xí)成本低:核心邏輯是 “SQL 映射”,只需掌握 XML / 注解與 SQL 的綁定,概念簡單清晰。
- 無額外依賴:輕量框架,僅需 MyBatis 核心包,無多余封裝,適合對依賴體積敏感的項目。
劣勢:
- 重復(fù)代碼多:基本 CRUD(增刪改查)需手動寫 SQL(即使邏輯簡單),Mapper 接口、XML 映射文件需一一對應(yīng),開發(fā)效率低。
- 動態(tài) SQL 繁瑣:復(fù)雜動態(tài) SQL 需寫大量 XML 標(biāo)簽(如
if/foreach/where),易出錯且維護困難(如標(biāo)簽嵌套、語法錯誤)。 - 功能需手動擴展:分頁、邏輯刪除等功能需自己實現(xiàn)(如自定義分頁插件、手動加
deleted判斷),無開箱即用的解決方案。
2. MyBatis-Plus 的優(yōu)劣
優(yōu)勢:
- 開發(fā)效率極高:繼承
BaseMapper即可實現(xiàn) 80% 以上的基礎(chǔ) CRUD,無需寫 SQL;條件構(gòu)造器簡化動態(tài) SQL,無需 XML 標(biāo)簽。 - 功能豐富且開箱即用:內(nèi)置分頁、邏輯刪除、自動填充、代碼生成器等功能,無需手動開發(fā),適合快速迭代的項目(如后臺管理系統(tǒng)、中小業(yè)務(wù))。
- 兼容 MyBatis:可無縫混合使用 MyBatis 語法(如復(fù)雜查詢?nèi)杂?XML 寫 SQL),既保留靈活性又提升效率。
- 降低新手門檻:無需熟練掌握 XML 動態(tài) SQL,通過條件構(gòu)造器的鏈?zhǔn)椒椒纯赏瓿纱蟛糠植樵儯率忠咨鲜帧?/li>
劣勢:
- 復(fù)雜查詢靈活性不足:雖然支持自定義 SQL,但過度依賴條件構(gòu)造器可能導(dǎo)致復(fù)雜查詢(如多表聯(lián)查 + 動態(tài)條件)寫法繁瑣,不如直接寫 SQL 直觀。
- 框架依賴增加:需引入 MyBatis-Plus 依賴,且部分功能(如代碼生成器)需額外配置,對 “輕量” 有要求的項目可能不適用。
- 底層 SQL 透明性低:條件構(gòu)造器生成的 SQL 需通過日志查看,若對 MP API 不熟悉,可能出現(xiàn) “預(yù)期外 SQL”(如條件拼接錯誤),排查問題成本高。
- 團隊學(xué)習(xí)成本:需掌握 MP 專屬 API(如條件構(gòu)造器方法、注解),若團隊成員不熟悉,可能出現(xiàn)用法不統(tǒng)一的問題。
四、總結(jié):如何選擇?
- 選 MyBatis:若項目業(yè)務(wù)復(fù)雜(多復(fù)雜查詢)、對 SQL 可控性要求高(需頻繁優(yōu)化),或團隊更習(xí)慣直接寫 SQL。
- 選 MyBatis-Plus:若項目以基礎(chǔ) CRUD 為主(如后臺管理系統(tǒng))、追求快速開發(fā),或需減少重復(fù)代碼(如自動填充、分頁),可大幅提升效率。
實際開發(fā)中,兩者常結(jié)合使用:基礎(chǔ) CRUD 用 MP 簡化開發(fā),復(fù)雜查詢用 MyBatis 的 XML 寫原生 SQL,兼顧效率與靈活性。
到此這篇關(guān)于MyBatis 和 MyBatis-Plus從語法詳解和優(yōu)劣對比的文章就介紹到這了,更多相關(guān)MyBatis 和 MyBatis-Plus對比內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用JWT創(chuàng)建解析令牌及RSA非對稱加密詳解
這篇文章主要介紹了JWT創(chuàng)建解析令牌及RSA非對稱加密詳解,JWT是JSON Web Token的縮寫,即JSON Web令牌,是一種自包含令牌,一種情況是webapi,類似之前的阿里云播放憑證的功能,另一種情況是多web服務(wù)器下實現(xiàn)無狀態(tài)分布式身份驗證,需要的朋友可以參考下2023-11-11
Spring MVC深入學(xué)習(xí)之啟動初始化過程
最近因為工作的原因在學(xué)習(xí)Spring MVC,為了更深入的學(xué)習(xí)Spring MVC,下面這篇文章主要給大家介紹了關(guān)于Spring MVC深入學(xué)習(xí)之啟動初始化過程的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧。2017-07-07
SpringCloud Alibaba項目實戰(zhàn)之nacos-server服務(wù)搭建過程
Nacos 是阿里巴巴推出來的一個新開源項目,這是一個更易于構(gòu)建云原生應(yīng)用的動態(tài)服務(wù)發(fā)現(xiàn)、配置管理和服務(wù)管理平臺。本章節(jié)重點給大家介紹SpringCloud Alibaba項目實戰(zhàn)之nacos-server服務(wù)搭建過程,感興趣的朋友一起看看吧2021-06-06
SpringBoot集成SFTP客戶端實現(xiàn)文件上傳下載實例
這篇文章主要為大家介紹了SpringBoot集成SFTP客戶端實現(xiàn)文件上傳下載實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-08-08
SpringBoot讀取resource目錄下文件失敗的原因及解決方案
在idea中運行時,有些resource下文件讀取工具類能夠正常獲取讀取到文件,但是通過java–jar的方式去運行jar包,此時resource下文件讀取工具類讀取文件就失效了,本文就給大家介紹一下SpringBoot讀取resource目錄下文件失敗解決方案,需要的朋友可以參考下2023-08-08
使用HttpServletResponse對象獲取請求行信息
這篇文章主要介紹了使用HttpServletResponse對象獲取請求行信息,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-02-02

