一.MP的原理
mp究竟是如何知道我們需要對哪個表進行操作,并且又是如何知道要操作哪些字段的呢?這是因為mp使用到了反射機制,我們在定義mapper接口時使其繼承了BaseMapper接口,并指定了BaseMapper接口泛型為User,因此mp可以通過掃描實體類并基于反射來找到表名為實體類名駝峰轉下劃線的表,再通過實體類中的字段和表中字段名的約定方式(如果mp遵循相關約定的話就可以找到)來找到其對應的數據庫字段。
簡單來說,就是通過反射,并且約定大于配置。

那么要使用mp要遵循哪些約定呢?
1.類名駝峰轉下劃線作為表名。
2.名為id的字段作為主鍵。
3.變量名駝峰轉下劃線作為表的字段名。
我們再定義表名和實體類的屬性時要保證相互遵循約定,才能一致。
二.常用注解
如果我們沒有遵循約定,那么我們該如何使用mp呢?這就要使用到mp為我們提供的注解了,常用的注解有以下幾個:

@TableName:當表名不是類名駝峰轉下劃線時,要在@TableName注解中指定表名。
@TableId:用來指定表中的主鍵字段信息,mp約定屬性名為id的字段作為主鍵。但是如果不叫id,那么可以通過該注解來手動指定。
特別注意:id字段不僅要指定value屬性,還要制定IdType屬性,即id的生成方式,目前有三種,AUTO:即由數據庫自增長。INPUT:由程序員自己去輸入。ASSIGN_ID:隨機分配ID,生成方式為雪花算法。
@TableField:用來指定表中的普通字段信息,如果表中的字段名不是變量名駝峰轉下劃線。那么就在該變量上手動自定表中的字段名。
三.@TableField注解的使用

@TableField注解在使用時的常見場景:
1.成員變量名和數據庫名不一致時,要使用@TableField注解來標明。
2.成員變量名以is開頭,并且是布爾值的情況下,mp會將is刪掉,把剩下的作為變量名,這樣就起不到駝峰轉下劃線的效果了,導致其與數據庫中的變量名不一樣(mp效果為married,而數據庫中為is_married)。因此碰到is開頭且類型為布爾類型的成員變量,要在其上加上@TableField注解來指定數據庫中的變量名。
3.成員變量名與數據庫關鍵字沖突,如order,這樣就需要在mp的@TableField注解中指定出來(@TableField("'order'"))
4.如果某一成員變量不是數據庫中的字段,也需要指出來,@TableField(exist = false)
四.代碼演示
package com.itheima.mp.domain.po;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;import java.time.LocalDateTime;@Data
@TableName("tb_user")
public class User {/*** 用戶id*/@TableId(type = IdType.AUTO)private Long id;/*** 用戶名*/@TableField("'username'")private String username;/*** 密碼*/@TableField(exist = false)private String password;/*** 注冊手機號*/private String phone;/*** 詳細信息*/private String info;/*** 使用狀態(1正常 2凍結)*/private Integer status;/*** 賬戶余額*/private Integer balance;/*** 創建時間*/private LocalDateTime createTime;/*** 更新時間*/private LocalDateTime updateTime;
}

我們首先測試@TableName注解,數據庫表名為tb_user,而實體類名稱為User。我們已在實體類上加上了注解。接著我們來測試該方法:
@Testvoid testQueryByIds() {
// List<User> users = userMapper.queryUserByIds(List.of(1L, 2L, 3L, 4L));List<User> users = userMapper.selectBatchIds(List.of(1L, 2L, 3L, 4L));users.forEach(System.out::println);}
成功,證明表明不一致時使用@TableName注解。

接著測試@TableId(type = IdType.AUTO),將測試方法中的testInsert方法中設置id語法注釋。

主鍵成功自增。
接著將該注解注釋掉。將測試方法中的testInsert方法中設置id語法注釋,再來測試。
package com.itheima.mp.mapper;import com.itheima.mp.domain.po.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.time.LocalDateTime;
import java.util.List;@SpringBootTest
class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testvoid testInsert() {User user = new User();
// user.setId(5L);user.setUsername("Lucy");user.setPassword("123");user.setPhone("18688990011");user.setBalance(200);user.setInfo("{\"age\": 24, \"intro\": \"英文老師\", \"gender\": \"female\"}");user.setCreateTime(LocalDateTime.now());user.setUpdateTime(LocalDateTime.now());
// userMapper.saveUser(user); 引入了mybatis-plus后,很多操作即可簡化,直接調用mp提供的現成方法即可userMapper.insert(user);}@Testvoid testSelectById() {
// User user = userMapper.queryUserById(5L);User user = userMapper.selectById(5L);System.out.println("user = " + user);}@Testvoid testQueryByIds() {
// List<User> users = userMapper.queryUserByIds(List.of(1L, 2L, 3L, 4L));List<User> users = userMapper.selectBatchIds(List.of(1L, 2L, 3L, 4L));users.forEach(System.out::println);}@Testvoid testUpdateById() {User user = new User();user.setId(5L);user.setBalance(20000);userMapper.updateById(user);
// userMapper.updateUser(user);}@Testvoid testDeleteUser() {
// userMapper.deleteUser(5L);userMapper.deleteById(5L);}
}
這樣就使用了雪花算法來進行操作,從而生成隨機的Long型id。也就是說,不設置IdType,默認使用雪花算法。?

接著測試@TableField("'? '")和@TableField(exist = false),執行以下方法:
@Testvoid testQueryByIds() {
// List<User> users = userMapper.queryUserByIds(List.of(1L, 2L, 3L, 4L));List<User> users = userMapper.selectBatchIds(List.of(1L, 2L, 3L, 4L));users.forEach(System.out::println);}
成功查詢出且字段以‘’標出(防止和sql語句關鍵字沖突),而且我們標記password為非數據庫字段,這里sql語句便沒有將password作為查詢條件。?

總結
