MyBatis?和?MyBatis-Plus從語法詳解和優(yōu)劣對(duì)比
MyBatis 和 MyBatis-Plus 是 Java 生態(tài)中常用的持久層框架,其中 MyBatis-Plus 是在 MyBatis 基礎(chǔ)上的增強(qiáng)工具(“只做增強(qiáng),不做改變”)。下面從語法詳解和優(yōu)劣對(duì)比兩部分展開說明。
一、MyBatis 語法詳解
MyBatis 的核心是 “SQL 映射”,通過 XML 或注解將 Java 方法與 SQL 語句綁定,需手動(dòng)定義 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,支持動(dòng)態(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對(duì)應(yīng)接口方法名,resultType對(duì)應(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}) <!-- #{屬性名}對(duì)應(yīng)實(shí)體類字段(需與數(shù)據(jù)庫字段映射) -->
</insert>
<!-- 3. 動(dòng)態(tài)SQL:批量刪除(if+foreach) -->
<delete id="deleteBatch">
DELETE FROM user
<where> <!-- where標(biāo)簽自動(dòng)處理多余的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. 動(dòng)態(tài)SQL:復(fù)雜查詢(choose/when/otherwise) -->
<select id="selectByCondition" resultType="User">
SELECT * FROM user
<where>
<choose> <!-- choose類似Java的switch:只執(zhí)行第一個(gè)滿足條件的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ā),核心是 “增強(qiáng) CRUD”—— 通過繼承接口、條件構(gòu)造器等簡化開發(fā),無需手動(dòng)寫基本 SQL,同時(shí)兼容 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 只需繼承它即可,無需手動(dòng)寫 SQL。
示例:
// 實(shí)體類(需與數(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+個(gè)方法: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(動(dòng)態(tài) SQL 簡化)
MP 提供 QueryWrapper(查詢條件)和 UpdateWrapper(更新條件),通過鏈?zhǔn)椒椒▌?dòng)態(tài)構(gòu)建條件,無需寫 XML 動(dòng)態(tài) SQL 標(biāo)簽。
示例 1:QueryWrapper(查詢條件)
public List<User> selectByCondition() {
// 構(gòu)建查詢條件:查詢年齡>20、用戶名含"張"、且創(chuàng)建時(shí)間在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)建時(shí)間降序
// 調(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(無需實(shí)體類)和條件構(gòu)造器
userMapper.update(null, updateWrapper);
}4. 分頁查詢(開箱即用)
MP 分頁插件配置后,直接用 IPage 接口即可實(shí)現(xiàn)分頁,無需手動(dòng)寫 LIMIT 語句:
public IPage<User> selectPage(int pageNum, int pageSize) {
// 1. 創(chuàng)建分頁對(duì)象(pageNum:頁碼,pageSize:每頁條數(shù))
IPage<User> page = new Page<>(pageNum, pageSize);
// 2. 調(diào)用selectPage方法(BaseMapper提供),傳入分頁對(duì)象和條件構(gòu)造器(null表示查所有)
return userMapper.selectPage(page, null);
// 返回結(jié)果包含:總條數(shù)(total)、總頁數(shù)(pages)、當(dāng)前頁數(shù)據(jù)(records)等
}5. 其他增強(qiáng)功能(語法涉及注解 / 配置)
邏輯刪除:通過 @TableLogic 注解標(biāo)記邏輯刪除字段(如 deleted),刪除時(shí)自動(dòng)改為 “更新 deleted=1”,查詢時(shí)自動(dòng)過濾 deleted=0:
@TableLogic // 標(biāo)記邏輯刪除字段 private Integer deleted;
自動(dòng)填充:通過 @TableField(fill = ...) 標(biāo)記需自動(dòng)填充的字段(如 createTime),配合 MetaObjectHandler 實(shí)現(xiàn)新增 / 更新時(shí)自動(dòng)賦值:
@TableField(fill = FieldFill.INSERT) // 新增時(shí)自動(dòng)填充
private LocalDateTime createTime;
// 自定義填充處理器
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
}
}代碼生成器:通過 AutoGenerator 自動(dòng)生成 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)劣對(duì)比
兩者核心差異在于 “開發(fā)效率” 與 “靈活性” 的權(quán)衡,具體對(duì)比如下:
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)化性能(如索引利用、查詢字段精簡),對(duì)底層 SQL 透明。
- 學(xué)習(xí)成本低:核心邏輯是 “SQL 映射”,只需掌握 XML / 注解與 SQL 的綁定,概念簡單清晰。
- 無額外依賴:輕量框架,僅需 MyBatis 核心包,無多余封裝,適合對(duì)依賴體積敏感的項(xiàng)目。
劣勢:
- 重復(fù)代碼多:基本 CRUD(增刪改查)需手動(dòng)寫 SQL(即使邏輯簡單),Mapper 接口、XML 映射文件需一一對(duì)應(yīng),開發(fā)效率低。
- 動(dòng)態(tài) SQL 繁瑣:復(fù)雜動(dòng)態(tài) SQL 需寫大量 XML 標(biāo)簽(如
if/foreach/where),易出錯(cuò)且維護(hù)困難(如標(biāo)簽嵌套、語法錯(cuò)誤)。 - 功能需手動(dòng)擴(kuò)展:分頁、邏輯刪除等功能需自己實(shí)現(xiàn)(如自定義分頁插件、手動(dòng)加
deleted判斷),無開箱即用的解決方案。
2. MyBatis-Plus 的優(yōu)劣
優(yōu)勢:
- 開發(fā)效率極高:繼承
BaseMapper即可實(shí)現(xiàn) 80% 以上的基礎(chǔ) CRUD,無需寫 SQL;條件構(gòu)造器簡化動(dòng)態(tài) SQL,無需 XML 標(biāo)簽。 - 功能豐富且開箱即用:內(nèi)置分頁、邏輯刪除、自動(dòng)填充、代碼生成器等功能,無需手動(dòng)開發(fā),適合快速迭代的項(xiàng)目(如后臺(tái)管理系統(tǒng)、中小業(yè)務(wù))。
- 兼容 MyBatis:可無縫混合使用 MyBatis 語法(如復(fù)雜查詢?nèi)杂?XML 寫 SQL),既保留靈活性又提升效率。
- 降低新手門檻:無需熟練掌握 XML 動(dòng)態(tài) SQL,通過條件構(gòu)造器的鏈?zhǔn)椒椒纯赏瓿纱蟛糠植樵?,新手易上手?/li>
劣勢:
- 復(fù)雜查詢靈活性不足:雖然支持自定義 SQL,但過度依賴條件構(gòu)造器可能導(dǎo)致復(fù)雜查詢(如多表聯(lián)查 + 動(dòng)態(tài)條件)寫法繁瑣,不如直接寫 SQL 直觀。
- 框架依賴增加:需引入 MyBatis-Plus 依賴,且部分功能(如代碼生成器)需額外配置,對(duì) “輕量” 有要求的項(xiàng)目可能不適用。
- 底層 SQL 透明性低:條件構(gòu)造器生成的 SQL 需通過日志查看,若對(duì) MP API 不熟悉,可能出現(xiàn) “預(yù)期外 SQL”(如條件拼接錯(cuò)誤),排查問題成本高。
- 團(tuán)隊(duì)學(xué)習(xí)成本:需掌握 MP 專屬 API(如條件構(gòu)造器方法、注解),若團(tuán)隊(duì)成員不熟悉,可能出現(xiàn)用法不統(tǒng)一的問題。
四、總結(jié):如何選擇?
- 選 MyBatis:若項(xiàng)目業(yè)務(wù)復(fù)雜(多復(fù)雜查詢)、對(duì) SQL 可控性要求高(需頻繁優(yōu)化),或團(tuán)隊(duì)更習(xí)慣直接寫 SQL。
- 選 MyBatis-Plus:若項(xiàng)目以基礎(chǔ) CRUD 為主(如后臺(tái)管理系統(tǒng))、追求快速開發(fā),或需減少重復(fù)代碼(如自動(dòng)填充、分頁),可大幅提升效率。
實(shí)際開發(fā)中,兩者常結(jié)合使用:基礎(chǔ) CRUD 用 MP 簡化開發(fā),復(fù)雜查詢用 MyBatis 的 XML 寫原生 SQL,兼顧效率與靈活性。
到此這篇關(guān)于MyBatis 和 MyBatis-Plus從語法詳解和優(yōu)劣對(duì)比的文章就介紹到這了,更多相關(guān)MyBatis 和 MyBatis-Plus對(duì)比內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
IDEA Ultimate2020.2版本配置Tomcat詳細(xì)教程
這篇文章主要介紹了IDEA Ultimate2020.2版本配置Tomcat教程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09
Java多條件判斷場景中規(guī)則執(zhí)行器的設(shè)計(jì)
近日在公司領(lǐng)到一個(gè)小需求,需要對(duì)之前已有的試用用戶申請(qǐng)規(guī)則進(jìn)行拓展。本文去掉if 判斷,試試用一個(gè)規(guī)則執(zhí)行器來替代它,感興趣的可以了解一下2021-06-06
SpringBoot如何打印mybatis的執(zhí)行sql問題
這篇文章主要介紹了SpringBoot如何打印mybatis的執(zhí)行sql問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03
mybatis自定義參數(shù)類型轉(zhuǎn)換器數(shù)據(jù)庫字段加密脫敏
這篇文章主要為大家介紹了mybatis自定義參數(shù)類型轉(zhuǎn)換器數(shù)據(jù)庫字段加密脫敏,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09

