介紹: MyBatis-Plus 是基於 MyBatis 框架的一個增強工具,主要目的是簡化 MyBatis 的開發過程,提供更加簡潔、方便的 CRUD 操作。它是在保留 MyBatis 強大功能的基礎上,通過封裝和優化一些常見操作來提高開發效率。 MyBatis-Plus 提供了許多開箱即用的功能 ...
介紹:
MyBatis-Plus 是基於 MyBatis 框架的一個增強工具,主要目的是簡化 MyBatis 的開發過程,提供更加簡潔、方便的 CRUD 操作。它是在保留 MyBatis 強大功能的基礎上,通過封裝和優化一些常見操作來提高開發效率。
MyBatis-Plus 提供了許多開箱即用的功能,包括自動 CRUD 代碼生成、分頁查詢、性能優化、以及支持多種資料庫。與 MyBatis 相比,MyBatis-Plus 的 部分 核心特性包括:
- 無侵入設計:不會改變 MyBatis 原有的 API 和使用方式,你可以自由選擇 MyBatis 和 MyBatis-Plus 的功能。
- 自動 CRUD:通過
BaseMapper
和ServiceImpl
介面,MyBatis-Plus 提供了一系列 CRUD 操作的方法,如insert
、delete
、update
和select
,減少了重覆的 SQL 編寫工作。 - 條件構造器:MyBatis-Plus 提供了條件構造器(如
QueryWrapper
),可以通過鏈式編程方式輕鬆構建複雜的查詢條件。
1、準備工作
1.1 添加依賴
創建一個 springboot
項目, 在 pom.xml
文件中的 dependencies 標簽中添加所需要的依賴。
打開 maven官網 搜索所需依賴。大家添加最新版本的就行
-
mybatis plus
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.7</version>
</dependency>
-
mysql
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>9.0.0</version>
</dependency>
-
mybatis spring
這個依賴最好加上,它可以解決部分 mybatis 和 spring 之間的相容性問題
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>3.0.4</version>
</dependency>
1.2 創建數據表和數據
在 mybatis plus 官網 給的有 sql 語句, 執行生成數據表和數據
在 application.properties
文件中添加下麵信息連接資料庫
spring.datasource.url=jdbc:mysql://localhost:3306/yourDatabaseName?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8
spring.datasource.username=YourUserName
spring.datasource.password=YourPassword
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
idea連接資料庫,創建pojo,mapper,service,controller文件就不多贅述了..
2、mapper層基本的操作
BaseMapper
是 MyBatis-Plus 提供的一個基礎 Mapper 介面,它簡化了數據訪問層(Data Access Layer)的開發。BaseMapper
提供了一系列通用的資料庫操作方法,這樣你就不必手動編寫常見的 SQL 語句,從而提升了開發效率。
1. 使用 BaseMapper
假設我們有一個用戶實體類 User
,如下:
public class User {
private Long id;
private String name;
private Integer age;
private String email;
// Getter 和 Setter
}
你可以創建一個 UserMapper
介面來繼承 BaseMapper<User>
:
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface UserMapper extends BaseMapper<User> {
// 你可以在這裡添加自定義方法
}
通過繼承 BaseMapper<User>
,UserMapper
立即擁有了所有的 CRUD 操作方法。你可以在你的服務層(Service Layer)中直接使用這些方法,無需再編寫任何 SQL 語句。
2. BaseMapper 提供的常用方法
2.1 增(Insert)
簡單示例:
// 定義用戶實體類
public class User {
private Long id;
private String username;
private String email;
}
// 使用 MyBatis-Plus 提供的 BaseMapper 介面
public interface UserMapper extends BaseMapper<User> {
}
// 插入一條記錄
User user = new User();
user.setUsername("john_doe");
user.setEmail("[email protected]");
// 調用 insert 方法
userMapper.insert(user);
解釋:這裡的 insert
方法直接使用實體類對象 user
,將其插入到資料庫中。MyBatis-Plus 自動生成的 insert
方法會根據實體類的屬性映射到資料庫表的欄位。
2.2 刪(Delete)
簡單示例:
// 根據 ID 刪除一條記錄
userMapper.deleteById(1L);
解釋:deleteById
方法通過傳入用戶的 id
刪除該用戶。這個方法直接刪除主鍵為 1
的用戶。
2.3 改(Update)
簡單示例:
// 創建一個用戶對象,設置要修改的欄位
User user = new User();
user.setId(1L); // 設置要更新的用戶 ID
user.setEmail("[email protected]"); // 修改用戶郵箱
// 更新用戶信息
userMapper.updateById(user);
解釋:updateById
方法根據 id
更新用戶記錄,這裡只更新了郵箱欄位,其他欄位保持不變。
2.4 查(Select)
簡單示例:
// 根據 ID 查詢用戶
User user = userMapper.selectById(1L);
// 輸出用戶信息
System.out.println(user.getUsername());
解釋:selectById
方法根據傳入的 id
查詢對應的用戶信息,然後可以輸出或使用這個用戶信息。
2.5 條件查詢
簡單示例:
// 構建查詢條件
QueryWrapper<User> queryWrapper = new QueryWrapper<>(); // <-------- 下麵會講到
queryWrapper.eq("username", "john_doe"); // 設置條件:用戶名為 john_doe
// 執行查詢
List<User> users = userMapper.selectList(queryWrapper);
// 輸出查詢結果
for (User u : users) {
System.out.println(u.getUsername());
}
解釋:QueryWrapper
是 MyBatis-Plus 提供的一個工具類,用於構建查詢條件。selectList
方法根據條件查詢所有符合條件的記錄。
3. 示例代碼
以下是如何使用 UserMapper
執行一些常見操作的示例:
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
// 插入一條記錄
public void addUser(User user) {
userMapper.insert(user);
}
// 根據 ID 刪除一條記錄
public void deleteUserById(Long id) {
userMapper.deleteById(id);
}
// 更新用戶信息
public void updateUser(User user) {
userMapper.updateById(user);
}
// 根據 ID 查詢用戶
public User getUserById(Long id) {
return userMapper.selectById(id);
}
// 查詢所有用戶
public List<User> getAllUsers() {
return userMapper.selectList(null);
}
}
3、service層基本的操作
ServiceImpl
和 IService
是 MyBatis-Plus 中用於服務層(Service Layer)的兩個重要介面和類,它們幫助簡化和規範了與資料庫交互的業務邏輯。下麵是它們的詳細介紹:
1. IService 介面
IService
是 MyBatis-Plus 提供的一個通用服務介面。它定義了一些常見的 CRUD(Create, Read, Update, Delete)操作,並將這些操作抽象成方法。這意味著,當你使用 IService
介面時,你無需自己手動編寫這些常見的資料庫操作方法。
IService 中的一些常用方法:
boolean save(T entity)
: 保存一個實體類對象到資料庫。boolean removeById(Serializable id)
: 根據 ID 刪除數據。boolean updateById(T entity)
: 根據 ID 更新數據。T getById(Serializable id)
: 根據 ID 查詢數據。List<T> list()
: 查詢所有數據。Page<T> page(Page<T> page)
: 分頁查詢數據。
2. ServiceImpl 類
ServiceImpl
是 MyBatis-Plus 提供的一個基礎實現類,它實現了 IService
介面中的方法。ServiceImpl
通常是被繼承的,它提供了具體的資料庫操作方法的實現。開發者只需在自己定義的服務實現類中繼承 ServiceImpl
類,就可以獲得預設的 CRUD 功能。
使用示例
假設你有一個用戶表 User
,併為其定義了一個實體類 User
和一個 Mapper 介面 UserMapper
。你可以定義一個服務介面 UserService
和一個服務實現類 UserServiceImpl
。
1. 定義服務介面:
public interface UserService extends IService<User> {
// 可以定義一些自定義的服務方法
}
2. 定義服務實現類:
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
// 你可以重寫 ServiceImpl 中的方法,或者定義更多的業務邏輯
}
在這個例子中,UserServiceImpl
繼承了 ServiceImpl<UserMapper, User>
並實現了 UserService
介面。通過這種方式,UserServiceImpl
類可以直接使用 ServiceImpl
提供的基本 CRUD 方法。
Mapper 和 Service 中有很多的方法,具體用法可以參考 Mybatis plus 官網
4、欄位映射
MyBatis-Plus 的自動映射規則主要涉及如何將資料庫表和欄位自動映射到 Java 實體類及其屬性。
1. 表名與實體類名的映射
- 預設規則:MyBatis-Plus 預設使用實體類名作為資料庫表名的首碼。比如,如果你的實體類名為
User
,那麼它會映射到名為user
的資料庫表。 - 自定義規則:你可以使用
@TableName
註解來指定自定義的表名。例如:@TableName("sys_user") public class User { // 屬性和方法 }
2. @TableField 欄位名與屬性名的映射
- 預設規則:欄位名和屬性名預設是直接映射的。例如,資料庫中的
user_name
欄位會映射到實體類中的userName
屬性。 - 駝峰命名規則:MyBatis-Plus 預設啟用了駝峰命名轉換。即,資料庫中的下劃線命名(如
user_name
)會被自動轉換為 Java 屬性的駝峰命名(如userName
)。 - 自定義欄位映射:可以使用
@TableField
註解來指定自定義的欄位名。例如:@TableField("user_name") private String userName;
@TableField
的其他用法:
-
如果表中欄位存在
sql語句的關鍵詞
,比如desc
, 那麼需要按照下麵的寫法, 否則mybatis plus 拼接含有desc欄位
的sql語句時會報錯@TableField("`desc`") private String desc;
-
@TableField(select = false)
作用:用於指定某個欄位在執行 SQL 查詢時不參與查詢,即在 SELECT 語句中不包含該欄位。
用途:通常用於那些只需要在資料庫操作中存在,但不需要在查詢結果中顯示的欄位。例如,邏輯刪除欄位、內部使用的欄位等@TableField(select = false) private Integer age;
-
@TableField(exist = false)
作用:用於指定某個欄位不對應資料庫中的任何欄位,即在資料庫表中不存在該欄位。
用途:通常用於那些只在 Java 實體中存在的欄位,但在資料庫表中沒有相應的欄位。例如,用於計算或臨時存儲的數據。@TableField(exist = false) private Integer age;
3. 主鍵的自動映射
在 MyBatis-Plus 中,@TableId
註解用於標識實體類中的主鍵欄位。@TableId
註解有兩個主要屬性:value
和 type
。它們分別用於指定欄位名和主鍵生成策略。
@TableId
註解屬性
-
value
:- 用途:指定資料庫表中的主鍵列名。它的值應該是資料庫表中實際的列名。
- 示例:如果資料庫表中的主鍵列名是
user_id
,則在實體類中可以這樣配置:@TableId(value = "user_id", type = IdType.ASSIGN_UUID) private String userId;
-
type
:-
用途:指定主鍵生成策略。MyBatis-Plus 提供了多種主鍵生成策略,
IdType
枚舉類定義了這些策略。 -
常用的生成策略:
IdType.AUTO
:資料庫自動生成(通常是自增長 ID)。IdType.INPUT
:用戶輸入 ID(即需要手動設置)。IdType.ASSIGN_ID
:由 MyBatis-Plus 生成的 ID(通常是 UUID)。IdType.ASSIGN_UUID
:生成 UUID(字元串類型的唯一 ID)。
-
示例:如果你想使用 UUID 作為主鍵,你可以使用
IdType.ASSIGN_UUID
:@TableId(value = "user_id", type = IdType.ASSIGN_UUID) private String userId;
-
5、條件構造器 常用查詢
MyBatis-Plus 提供了強大的條件構造器,使得在查詢資料庫時可以靈活地構建條件,而無需手動編寫複雜的 SQL 語句。主要通過 Wrapper
介面及其常用實現類 QueryWrapper
和 LambdaQueryWrapper
來實現條件查詢。
1. Wrapper
介面
Wrapper
是 MyBatis-Plus 提供的條件構造器介面,用於構建動態 SQL。它有多個實現類,其中最常用的是 QueryWrapper
和 LambdaQueryWrapper
。
2. QueryWrapper
QueryWrapper
是 MyBatis-Plus 提供的一個通用條件構造器,用於以非 Lambda 表達式的方式構建查詢條件。
常用方法:
- eq: 等於
- ne: 不等於
- gt: 大於
- ge: 大於等於
- lt: 小於
- le: 小於等於
- between: 在兩者之間
- like: 模糊查詢
- or: 或條件
- and: 並且條件
- orderByAsc: 升序排序
- orderByDesc: 降序排序
- in: 在指定範圍內
- inSql: 允許你使用子查詢的結果集作為 IN 條件的範圍
- isNull: 判斷欄位是否為 NULL
- isNotNull: 判斷欄位是否不為 NULL
示例:
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper
.eq("name", "張三") // name 等於 張三。 eq也可以寫三個參數, 第一個參數是boolean, false 表示這個條件不起作用, true 表示起作用
.ge("age", 18) // age 大於等於 18
.like("email", "gmail.com") // email 包含 gmail.com
.orderByDesc("create_time"); // 按 create_time 降序排列
List<User> users = userMapper.selectList(queryWrapper);
3. LambdaQueryWrapper
LambdaQueryWrapper
是 QueryWrapper
的 Lambda 版本,用於在構建條件時避免使用字元串來指定欄位,增加了類型安全性。它推薦使用欄位的 Lambda 表達式來構建條件。
示例:
LambdaQueryWrapper<User> lambdaQuery = new LambdaQueryWrapper<>();
lambdaQuery
.eq(User::getName, "張三") // name 等於 張三
.ge(User::getAge, 18) // age 大於等於 18
.like(User::getEmail, "gmail.com") // email 包含 gmail.com
.orderByDesc(User::getCreateTime); // 按 create_time 降序排列
List<User> users = userMapper.selectList(lambdaQuery);
4. UpdateWrapper
和 LambdaUpdateWrapper
這兩個類分別是用於構建更新條件的構造器,功能與 QueryWrapper
和 LambdaQueryWrapper
類似,但用於 UPDATE
操作。
示例:
UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
updateWrapper
.eq("name", "張三")
.set("age", 30); // 將年齡更新為 30
userMapper.update(null, updateWrapper);
具體用法可參考 Mybatis plus 官網
6、高級查詢
6.1 分組查詢
示例 :按 age
分組並統計人數
假設你想統計各個年齡段的人數,可以使用如下代碼:
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.select("age", "COUNT(*) as count");
queryWrapper.groupBy("age");
List<Map<String, Object>> result = userMapper.selectMaps(queryWrapper);
生成的 SQL:
SELECT age, COUNT(*) as count FROM user GROUP BY age;
6.2 聚合查詢
示例 :按 age
分組並過濾統計結果(HAVING
)
如果你只想統計人數大於 1 的年齡段,可以添加 HAVING
條件:
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.select("age", "COUNT(*) as count");
queryWrapper.groupBy("age");
queryWrapper.having("COUNT(*) > 1");
List<Map<String, Object>> result = userMapper.selectMaps(queryWrapper);
生成的 SQL:
SELECT age, COUNT(*) as count FROM user GROUP BY age HAVING COUNT(*) > 1;
6.3 排序查詢
示例 1:按 age
升序和 name
升序排序
假設你想首先按用戶的年齡升序排序,然後按姓名升序排序,可以使用如下代碼:
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.orderByAsc("age").orderByAsc("name");
List<User> result = userMapper.selectList(queryWrapper);
生成的 SQL:
SELECT * FROM user ORDER BY age ASC, name ASC;
示例 2:按 age
降序排序
假設你想按用戶的年齡降序排序,可以使用如下代碼:
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.orderByDesc("age");
List<User> result = userMapper.selectList(queryWrapper);
生成的 SQL:
SELECT * FROM user ORDER BY age DESC;
示例 3:按 age
升序和 name
降序組合排序
假設你想先按年齡升序排序,再按姓名降序排序,可以使用如下代碼:
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.orderByAsc("age").orderByDesc("name");
List<User> result = userMapper.selectList(queryWrapper);
生成的 SQL:
SELECT * FROM user ORDER BY age ASC, name DESC;
示例 4:按多欄位排序,並指定是否為空
假設你想按 age
升序排序,並希望將 name
為空的記錄排在前面,可以使用如下代碼:
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.orderByAsc("age").orderByAsc("name", true);
List<User> result = userMapper.selectList(queryWrapper);
生成的 SQL:
SELECT * FROM user ORDER BY age ASC, name ASC;
6.4 邏輯查詢
func
方法是 MyBatis-Plus 提供的一個非常靈活的功能,它允許你將一段自定義的邏輯包裝到查詢條件中。這對於需要根據不同的條件來動態構建查詢的場景特別有用。下麵是對 func
方法的詳細解釋。
1. func
方法的基本用法
func
方法接收一個 Consumer
,該 Consumer
的參數是 QueryWrapper
(或 LambdaQueryWrapper
)的一個實例。你可以在這個 Consumer
中編寫自定義的邏輯,並根據不同的條件來動態地添加或修改查詢條件。
語法結構
queryWrapper.func(wrapper -> {
// 在這裡編寫自定義邏輯
if (condition) {
wrapper.eq("column", value);
} else {
wrapper.ne("column", value);
}
});
主要參數
Consumer<QueryWrapper>
或Consumer<LambdaQueryWrapper>
:這是一個函數式介面,允許你傳入一個 Lambda 表達式或方法引用。你可以在這個介面的accept
方法中實現自己的邏輯。
實際應用場景
假設你有一個用戶查詢介面,允許用戶根據不同的條件來過濾結果,例如按 id
或按 name
。你可以使用 func
來根據用戶輸入動態地構建查詢條件。
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.func(wrapper -> {
if (userInput != null && userInput.isValid()) {
wrapper.eq(User::getName, userInput.getName());
} else {
wrapper.ne(User::getId, 1);
}
});
List<User> users = userMapper.selectList(lambdaQueryWrapper);
- 示例解釋:
- 如果
userInput
非空且有效,則查詢條件為name = userInput.getName()
。 - 否則,查詢條件為
id != 1
。
- 如果
2. and
和 or
的使用
在 MyBatis-Plus 中,and
和 or
用於在構建查詢條件時處理多條件的邏輯運算。它們允許你在查詢中組合多個條件,以實現複雜的查詢邏輯。
and
方法
and
方法用於將多個查詢條件通過邏輯“與” (AND
) 連接在一起。它將多個條件組合成一個大的 AND
條件,從而要求所有這些條件都必須滿足。
示例
假設你有一個 User
表,你想查詢年齡大於 20 且名字為 "Jack" 的用戶。可以使用以下代碼:
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.gt("age", 20).and(wrapper -> wrapper.eq("name", "Jack"));
List<User> users = userMapper.selectList(queryWrapper);
生成的 SQL:
SELECT * FROM user WHERE age > 20 AND name = 'Jack';
在這個例子中,and
方法的作用是將 .gt("age", 20)
和 .eq("name", "Jack")
這兩個條件通過 AND
組合在一起。
or
方法
or
方法用於將多個查詢條件通過邏輯“或” (OR
) 連接在一起。它將多個條件組合成一個大的 OR
條件,只要其中一個條件滿足,就會返回符合的結果。
示例
假設你有一個 User
表,你想查詢年齡大於 20 或名字為 "Jack" 的用戶。可以使用以下代碼:
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.gt("age", 20).or(wrapper -> wrapper.eq("name", "Jack"));
List<User> users = userMapper.selectList(queryWrapper);
生成的 SQL:
SELECT * FROM user WHERE age > 20 OR name = 'Jack';
在這個例子中,or
方法的作用是將 .gt("age", 20)
和 .eq("name", "Jack")
這兩個條件通過 OR
組合在一起。
組合使用 and
和 or
你還可以結合使用 and
和 or
方法,以構建更複雜的查詢。例如,如果你想查詢年齡大於 20 且(名字為 "Jack" 或郵箱為 "[email protected]")的用戶,可以使用以下代碼:
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.gt("age", 20)
.and(wrapper -> wrapper.eq("name", "Jack")
.or().eq("email", "[email protected]"));
List<User> users = userMapper.selectList(queryWrapper);
生成的 SQL:
SELECT * FROM user WHERE age > 20 AND (name = 'Jack' OR email = '[email protected]');
在這個例子中,and
和 or
方法的結合使用允許你在 age > 20
的基礎上,增加一個組合條件 (name = 'Jack' OR email = '[email protected]')
。
6.5 其他查詢
apply
方法
apply
方法允許你直接在 QueryWrapper
中插入自定義的 SQL 片段。apply 方法中的 SQL 片段會被添加到 WHERE 子句的末尾。這允許你在現有的查詢條件基礎上,添加更複雜的條件或函數。
基本用法:
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.apply("DATE_FORMAT(create_time, '%Y-%m-%d') = {0}", "2024-09-01");
在這個示例中:
apply
方法接受一個 SQL 片段作為第一個參數,並可以通過{}
占位符來插入參數。- 這裡使用了
DATE_FORMAT
函數來格式化create_time
欄位,並將其與特定的日期進行比較。
last
方法
last
方法用於在生成的 SQL 查詢的末尾添加額外的 SQL 片段。通常用於添加額外的 SQL 語句,如 ORDER BY
, LIMIT
, OFFSET
等,這些操作是在生成的 SQL 的最後部分進行的。
基本用法:
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.last("LIMIT 5");
在這個示例中:
last
方法添加了一個LIMIT 5
子句到查詢的末尾,用於限制結果集的返回行數。
示例
假設你有一個 User
表,並且想要查詢所有 age
大於 20 的用戶,並且結果按照 id
降序排列,並且只返回前 10 條記錄。你可以使用 apply
和 last
方法來實現這個需求:
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.gt("age", 20) // age > 20
.orderByDesc("id") // 按 id 降序排序
.last("LIMIT 10"); // 限制返回結果為前 10 條
以上內容包含了 mybatis plus
的大部分常用內容,基本能滿足大部分需求。
其他內容 ... 待更~