目錄
- 第一章 MyBatis-Plus3概述
- 1.1、簡介
- 1.2、特性
- 1.3、框架結構
- 1.4、專案地址
- 1.5、版本介紹
- 1.6、快速安裝
- 1.7、開發環境
- 第二章 MyBatis-Plus3增刪改查
- 2.1、專案搭建
- 2.2、專案配置(1)
- 2.3、專案配置(2)
- 2.4、資料匯入
- 2.5、創建物體
- 2.6、創建介面
- 2.7、測驗準備
- 2.8、增刪改查
- 2.8.1、insert
- 2.8.2、updateById
- 2.8.3、selectById
- 2.8.4、selectByMap
- 2.8.5、selectBatchIds
- 2.8.6、deleteById
- 2.8.7、deleteByMap
- 2.8.8、deleteBatchIds
- 第三章 MyBatis-Plus3注解介紹
- 3.1、@TableName
- 3.2、@TableId
- 3.3、@TableField
- 3.4、@Version
- 3.5、@EnumValue
- 3.6、@TableLogic
- 3.7、@SqlParser
- 3.8、@KeySequence
- 第四章 MyBatis-Plus3條件構造器
- 4.1、資料匯入
- 4.2、構造器簡介
- 4.3、構造器使用(1)
- 4.3.1、帶條件的查詢
- 4.3.2、帶條件的修改
- 4.3.3、帶條件的洗掉
- 4.4、構造器使用(2)
- 4.4.1、allEq
- 4.4.2、eq
- 4.4.3、ne
- 4.4.4、gt
- 4.4.5、ge
- 4.4.6、lt
- 4.4.7、le
- 4.4.8、between
- 4.4.9、notBetween
- 4.4.10、like
- 4.4.11、notLike
- 4.4.12、likeLeft
- 4.4.13、likeRight
- 4.4.14、isNull
- 4.4.15、isNotNull
- 4.4.16、in
- 4.4.17、notIn
- 4.4.18、inSql
- 4.4.19、notInSql
- 4.4.20、groupBy
- 4.4.21、orderByAsc
- 4.4.22、orderByDesc
- 4.4.23、orderBy
- 4.4.24、having
- 4.4.25、func
- 4.4.26、or
- 4.4.27、and
- 4.4.28、nested
- 4.4.29、apply
- 4.4.30、last
- 4.4.31、exists
- 4.4.32、notExists
- 第五章 MyBatis-Plus3代碼生成器
- 5.1、資料匯入
- 5.2、代碼生成器簡介
- 5.3、代碼生成器使用
- 5.3.1、添加依賴
- 5.3.2、添加配置
- 5.3.3、啟動配置
- 5.3.4、代碼生成
- 5.3.5、工程結構
- 5.3.6、添加代碼
- 5.3.7、啟動運行
- 5.3.8、測驗方法
- 5.3.9、溫馨提示
- 5.4、代碼生成器方法
- 5.4.1、save
- 5.4.2、saveOrUpdate
- 5.4.3、remove
- 5.4.4、update
- 5.4.5、get
- 5.4.6、list
- 5.4.7、page
- 5.4.8、count
- 5.4.9、chain
- 第六章 MyBatis-Plus3配置詳解
- 6.1、配置概述
- 6.2、配置方式
- 6.3、配置選項
- 6.3.1、mapperLocations
- 6.3.2、typeAliasesPackage
- 6.3.3、typeHandlersPackage
- 6.3.4、typeEnumsPackage
- 6.3.5、checkConfigLocation
- 6.3.6、executorType
- 6.3.7、configurationProperties
- 6.3.8、configuration
- 6.3.8.1、mapUnderscoreToCamelCase
- 6.3.8.2、defaultEnumTypeHandler
- 6.3.8.3、aggressiveLazyLoading
- 6.3.8.4、autoMappingBehavior
- 6.3.8.5、autoMappingUnknownColumnBehavior
- 6.3.8.6、localCacheScope
- 6.3.8.7、cacheEnabled
- 6.3.8.8、callSettersOnNulls
- 6.3.8.9、configurationFactory
- 6.3.8.10、MyBatis3的配置屬性
- 6.3.9、globalConfig
- 6.3.9.1、banner
- 6.3.9.2、enableSqlRunner
- 6.3.9.3、superMapperClass
- 6.3.9.4、dbConfig
- 6.3.9.4.1、idType
- 6.3.9.4.2、tablePrefix
- 6.3.9.4.3、schema
- 6.3.9.4.4、columnFormat
- 6.3.9.4.5、propertyFormat
- 6.3.9.4.6、tableUnderline
- 6.3.9.4.7、capitalMode
- 6.3.9.4.8、logicDeleteField
- 6.3.9.4.9、logicDeleteValue
- 6.3.9.4.10、logicNotDeleteValue
- 6.3.9.4.11、insertStrategy
- 6.3.9.4.12、updateStrategy
- 6.3.9.4.13、selectStrategy
- 6.4、配置小結
- 第七章 MyBatis-Plus3插件擴展
- 7.1、分頁插件
- 7.2、執行分析插件
- 7.3、性能分析插件
- 7.4、樂觀鎖插件
- 7.5、快速開發插件
- 第八章 MyBatis-Plus3其它功能
- 8.1、Sql 注入器
- 8.2、邏輯洗掉
- 8.3、通用列舉
- 8.3.1、保存列舉值
- 8.3.2、保存列舉名稱
- 8.4、自動填充功能
- 8.5、欄位型別處理器
- 8.6、自定義ID生成器
- 8.7、Sequence主鍵
配套資料,免費下載
鏈接:https://pan.baidu.com/s/1yQS9hGP3r_zZbkuo-jlijA
提取碼:4v88
復制這段內容后打開百度網盤手機App,操作更方便哦
第一章 MyBatis-Plus3概述
1.1、簡介
MyBatis-Plus(簡稱 MP)是一個 MyBatis 的增強工具,在 MyBatis 的基礎上只做增強不做改變,為簡化開發、提高效率而生,
我們的愿景是成為 MyBatis 最好的搭檔,就像魂斗羅中的1P、2P,基友搭配,效率翻倍,
1.2、特性
- 無侵入:只做增強不做改變,引入它不會對現有工程產生影響,如絲般順滑
- 損耗小:啟動即會自動注入基本 CURD,性能基本無損耗,直接面向物件操作
- 強大的 CRUD 操作:內置通用 Mapper、通用 Service,僅僅通過少量配置即可實作單表大部分 CRUD 操作,更有強大的條件構造器,滿足各類使用需求
- 支持 Lambda 形式呼叫:通過 Lambda 運算式,方便的撰寫各類查詢條件,無需再擔心欄位寫錯
- 支持主鍵自動生成:支持多達 4 種主鍵策略(內含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解決主鍵問題
- 支持 ActiveRecord 模式:支持 ActiveRecord 形式呼叫,物體類只需繼承 Model 類即可進行強大的 CRUD 操作
- 支持自定義全域通用操作:支持全域通用方法注入( Write once, use anywhere )
- 內置代碼生成器:采用代碼或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 層代碼,支持模板引擎,更有超多自定義配置等您來使用
- 內置分頁插件:基于 MyBatis 物理分頁,開發者無需關心具體操作,配置好插件之后,寫分頁等同于普通 List 查詢
- 分頁插件支持多種資料庫:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多種資料庫
- 內置性能分析插件:可輸出 Sql 陳述句以及其執行時間,建議開發測驗時啟用該功能,能快速揪出慢查詢
- 內置全域攔截插件:提供全表 delete 、 update 操作智能分析阻斷,也可自定義攔截規則,預防誤操作
1.3、框架結構

1.4、專案地址
官網地址:點擊打開
原始碼地址:點擊打開
檔案地址:點擊打開
配置地址:點擊打開
1.5、版本介紹
全新的 MyBatis-Plus 3.0 版本基于 JDK8,提供了 lambda 形式的呼叫,所以安裝集成 MP3.0 要求如下:
- JDK 8+
- Maven or Gradle
1.6、快速安裝
-
Spring Boot
-
Maven:
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.0</version> </dependency> -
Gradle:
compile group: 'com.baomidou', name: 'mybatis-plus-boot-starter', version: '3.4.0'
-
-
Spring MVC
-
Maven:
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus</artifactId> <version>3.4.0</version> </dependency> -
Gradle:
compile group: 'com.baomidou', name: 'mybatis-plus', version: '3.4.0'
-
警告:引入
MyBatis-Plus之后請不要再次引入MyBatis以及MyBatis-Spring,以避免因版本差異導致的問題,
1.7、開發環境
- Jdk:jdk1.8.0_261
- Idea:IntelliJ IDEA 2020.1.2 x64
- Maven:apache-maven-3.3.9
- MySQL:mysql-5.5.61-win64
第二章 MyBatis-Plus3增刪改查
2.1、專案搭建




新建完成以后,打開pom.xml后添加以下依賴:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
在src/mian/java目錄中,創建以下包檔案
- com.caochenlei.mpdemo.pojo
- com.caochenlei.mpdemo.mapper
2.2、專案配置(1)
MyBatis-Plus 的配置例外的簡單,我們僅需要一些簡單的配置即可使用 MyBatis-Plus 的強大功能!
-
Spring Boot 工程:
-
配置 MapperScan 注解
@SpringBootApplication @MapperScan("com.caochenlei.mpdemo.mapper") public class MpDemoApplication { public static void main(String[] args) { SpringApplication.run(MpDemoApplication.class, args); } }
-
-
Spring MVC 工程:
-
配置 MapperScan 物件
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.caochenlei.mpdemo.mapper"/> </bean> -
調整 SqlSessionFactory 為 MyBatis-Plus 的 SqlSessionFactory
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> </bean>
-
2.3、專案配置(2)
application.properties
#mysql
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mp?useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=123456
#mybatis-plus
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
2.4、資料匯入
## 創建庫
CREATE DATABASE mp;
## 使用庫
USE mp;
## 創建表
CREATE TABLE tbl_employee(
id INT(11) PRIMARY KEY AUTO_INCREMENT,
last_name VARCHAR(50),
email VARCHAR(50),
gender CHAR(1),
age INT
);
## 匯入資料
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Tom','tom@qq.com',1,22);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Jerry','jerry@qq.com',0,25);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Black','black@qq.com',1,30);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('White','white@qq.com',0,35);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Tiger','tiger@qq.com',1,28);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Bobby','bobby@qq.com',0,16);
## 查詢資料
SELECT * FROM tbl_employee;
2.5、創建物體
com.caochenlei.mpdemo.pojo.Employee
@TableName("tbl_employee")
public class Employee {
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@TableField(value = "last_name")
private String lastName;
@TableField(value = "email")
private String email;
@TableField(value = "gender")
private Integer gender;
@TableField(value = "age")
private Integer age;
public Employee() {}
public Employee(Integer id, String lastName, String email, Integer gender, Integer age) {
this.id = id;
this.lastName = lastName;
this.email = email;
this.gender = gender;
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getGender() {
return gender;
}
public void setGender(Integer gender) {
this.gender = gender;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Employee{" +
"id=" + id +
", lastName='" + lastName + '\'' +
", email='" + email + '\'' +
", gender=" + gender +
", age=" + age +
'}';
}
}
2.6、創建介面
com.caochenlei.mpdemo.mapper.EmployeeMapper
@Repository
public interface EmployeeMapper extends BaseMapper<Employee> {
}
2.7、測驗準備
com.caochenlei.mpdemo.MpDemoApplicationTests
@SpringBootTest
class MpDemoApplicationTests {
@Autowired
private EmployeeMapper employeeMapper;
@Test
void contextLoads() {
List<Employee> employees = employeeMapper.selectList(null);
employees.forEach(System.out::println);
}
}
2.8、增刪改查
2.8.1、insert
需求描述:插入一個員工,員工姓名為“張三”、郵箱為"zhangsan@qq.com"、男性、25歲
@Test
void testInsert() {
int result = employeeMapper.insert(new Employee(null, "zhangsan", "zhangsan@qq.com", 0, 25));
System.out.println("result:" + result);
}
2.8.2、updateById
需求資訊:將id為1的員工的姓名更改為"Jennie"
@Test
void testUpdateById() {
// 先查詢
Employee employee = employeeMapper.selectById(1);
employee.setLastName("Jennie");
// 再修改
int result = employeeMapper.updateById(employee);
System.out.println(result);
}
2.8.3、selectById
需求描述:查詢id為1的員工資訊
@Test
void testSelectById() {
Employee employee = employeeMapper.selectById(1);
System.out.println(employee);
}
2.8.4、selectByMap
需求描述:查詢性別為男性(0)且年齡在25歲的員工資訊
@Test
void testSelectByMap() {
Map<String, Object> map = new HashMap<>();
map.put("gender",0);
map.put("age",25);
List<Employee> employees = employeeMapper.selectByMap(map);
employees.forEach(System.out::println);
}
2.8.5、selectBatchIds
需求描述:查詢id分別為1、2、3的員工的資訊
@Test
void testSelectBatchIds() {
List<Employee> employees = employeeMapper.selectBatchIds(Arrays.asList(1, 2, 3));
employees.forEach(System.out::println);
}
2.8.6、deleteById
需求資訊:洗掉id為1的員工資訊
@Test
void testDeleteById() {
int result = employeeMapper.deleteById(1);
System.out.println(result);
}
2.8.7、deleteByMap
需求描述:洗掉性別為男性(0)且年齡在25歲的員工資訊
@Test
void testDeleteByMap() {
Map<String, Object> map = new HashMap<>();
map.put("gender", 0);
map.put("age", 25);
int result = employeeMapper.deleteByMap(map);
System.out.println(result);
}
2.8.8、deleteBatchIds
需求描述:洗掉id分別為4、5、6的員工的資訊
@Test
void testDeleteBatchIds() {
int result = employeeMapper.deleteBatchIds(Arrays.asList(4, 5, 6));
System.out.println(result);
}
第三章 MyBatis-Plus3注解介紹
3.1、@TableName
描述:表名注解
| 屬性 | 型別 | 必須指定 | 默認值 | 描述 |
|---|---|---|---|---|
| value | String | 否 | “” | 表名 |
| schema | String | 否 | “” | schema |
| keepGlobalPrefix | boolean | 否 | false | 是否保持使用全域的 tablePrefix 的值(如果設定了全域 tablePrefix 且自行設定了 value 的值) |
| resultMap | String | 否 | “” | xml 中 resultMap 的 id |
| autoResultMap | boolean | 否 | false | 是否自動構建 resultMap 并使用(如果設定 resultMap 則不會進行 resultMap 的自動構建并注入) |
3.2、@TableId
描述:主鍵注解
| 屬性 | 型別 | 必須指定 | 默認值 | 描述 |
|---|---|---|---|---|
| value | String | 否 | “” | 主鍵欄位名 |
| type | Enum | 否 | IdType.NONE | 主鍵型別 |
IdType
| 值 | 描述 |
|---|---|
| AUTO | 資料庫ID自增 |
| NONE | 無狀態,該型別為未設定主鍵型別(注解里等于跟隨全域,全域里約等于 INPUT) |
| INPUT | insert前自行set主鍵值 |
| ASSIGN_ID | 分配ID(主鍵型別為Number(Long和Integer)或String)(since 3.3.0),使用介面IdentifierGenerator的方法nextId(默認實作類為DefaultIdentifierGenerator雪花演算法) |
| ASSIGN_UUID | 分配UUID,主鍵型別為String(since 3.3.0),使用介面IdentifierGenerator的方法nextUUID(默認default方法) |
3.3、@TableField
描述:欄位注解(非主鍵)
| 屬性 | 型別 | 必須指定 | 默認值 | 描述 |
|---|---|---|---|---|
| value | String | 否 | “” | 資料庫欄位名 |
| el | String | 否 | “” | 映射為原生 #{ ... } 邏輯,相當于寫在 xml 里的 #{ ... } 部分 |
| exist | boolean | 否 | true | 是否為資料庫表欄位 |
| condition | String | 否 | “” | 欄位 where 物體查詢比較條件,有值設定則按設定的值為準,沒有則為默認全域的 %s=#{%s} |
| update | String | 否 | “” | 欄位 update set 部分注入, 例如:update="%s+1":表示更新時會set version=version+1(該屬性優先級高于 el 屬性) |
| insertStrategy | Enum | N | DEFAULT | 舉例:NOT_NULL: insert into table_a(<if test="columnProperty != null">column</if>) values (<if test="columnProperty != null">#{columnProperty}</if>) |
| updateStrategy | Enum | N | DEFAULT | 舉例:IGNORED: update table_a set column=#{columnProperty} |
| whereStrategy | Enum | N | DEFAULT | 舉例:NOT_EMPTY: where <if test="columnProperty != null and columnProperty!=''">column=#{columnProperty}</if> |
| fill | Enum | 否 | FieldFill.DEFAULT | 欄位自動填充策略 |
| select | boolean | 否 | true | 是否進行 select 查詢 |
| keepGlobalFormat | boolean | 否 | false | 是否保持使用全域的 format 進行處理 |
| jdbcType | JdbcType | 否 | JdbcType.UNDEFINED | JDBC型別 (該默認值不代表會按照該值生效) |
| typeHandler | Class<? extends TypeHandler> | 否 | UnknownTypeHandler.class | 型別處理器 (該默認值不代表會按照該值生效) |
| numericScale | String | 否 | “” | 指定小數點后保留的 |
FieldStrategy
| 值 | 描述 |
|---|---|
| IGNORED | 忽略判斷 |
| NOT_NULL | 非NULL判斷 |
| NOT_EMPTY | 非空判斷(只對字串型別欄位,其他型別欄位依然為非NULL判斷) |
| DEFAULT | 追隨全域配置 |
FieldFill
| 值 | 描述 |
|---|---|
| DEFAULT | 默認不處理 |
| INSERT | 插入時填充欄位 |
| UPDATE | 更新時填充欄位 |
| INSERT_UPDATE | 插入和更新時填充欄位 |
3.4、@Version
描述:樂觀鎖注解、標記 @Verison 在欄位上
3.5、@EnumValue
描述:通列舉類注解(注解在列舉欄位上)
3.6、@TableLogic
描述:表欄位邏輯處理注解(邏輯洗掉)
| 屬性 | 型別 | 必須指定 | 默認值 | 描述 |
|---|---|---|---|---|
| value | String | 否 | “” | 邏輯未洗掉值 |
| delval | String | 否 | “” | 邏輯洗掉值 |
3.7、@SqlParser
描述:租戶注解,支持method上以及mapper介面上
| 屬性 | 型別 | 必須指定 | 默認值 | 描述 |
|---|---|---|---|---|
| filter | boolean | 否 | false | true: 表示過濾SQL決議,即不會進入ISqlParser決議鏈,否則會進決議鏈并追加例如tenant_id等條件 |
3.8、@KeySequence
描述:序列主鍵策略 oracle
屬性:value、resultMap
| 屬性 | 型別 | 必須指定 | 默認值 | 描述 |
|---|---|---|---|---|
| value | String | 否 | “” | 序列名 |
| clazz | Class | 否 | Long.class | id的型別, 可以指定String.class,這樣回傳的Sequence值是字串"1" |
第四章 MyBatis-Plus3條件構造器
4.1、資料匯入
## 使用庫
USE mp;
## 清空表
TRUNCATE TABLE tbl_employee;
## 匯入資料
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Allan0','123@qq.com',0,21);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Allan1','123@qq.com',0,22);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Allan2','123@qq.com',0,23);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Allan3','123@qq.com',0,24);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Allan4','123@qq.com',0,25);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Allan5','123@qq.com',0,26);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Allan6','123@qq.com',0,27);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Allan7','123@qq.com',0,28);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Allan8','123@qq.com',0,29);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Allan9','123@qq.com',0,30);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Baby0','123@qq.com',1,21);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Baby1','123@qq.com',0,22);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Baby2','123@qq.com',1,23);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Baby3','123@qq.com',0,24);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Baby4','123@qq.com',1,25);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Baby5','123@qq.com',0,26);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Baby6','123@qq.com',1,27);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Baby7','123@qq.com',0,28);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Baby8','123@qq.com',1,29);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Baby9','123@qq.com',0,30);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Tom0','123@qq.com',1,21);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Tom1','123@qq.com',0,22);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Tom2','123@qq.com',1,23);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Tom3','123@qq.com',0,24);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Tom4','123@qq.com',1,25);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Tom5','123@qq.com',0,26);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Tom6','123@qq.com',1,27);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Tom7','123@qq.com',0,28);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Tom8','123@qq.com',1,29);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Tom9','123@qq.com',0,30);
## 查詢資料
SELECT * FROM tbl_employee;
4.2、構造器簡介
MyBatis-Plus 通過 EntityWrapper(簡稱 EW,MP 封裝的一個查詢條件構造器)或者 Condition(與 EW 類似) 來讓用戶自由的構建查詢條件,簡單便捷,沒有額外的負擔, 能夠有效提高開發效率,它主要用于處理 sql 拼接,排序,物體引數查詢等,
注意:使用的是資料庫欄位,不是 Java 屬性!
警告:MyBatis-Plus不支持以及不贊成在 RPC 呼叫中把 Wrapper 進行傳輸,Wrapper 很重,傳輸 Wrapper 可以類比為你的 controller 用 map 接收值(開發一時爽,維護火葬場),正確的 RPC 呼叫姿勢是寫一個 DTO 進行傳輸,被呼叫方再根據 DTO 執行相應的操作,
4.3、構造器使用(1)
4.3.1、帶條件的查詢
需求描述:查詢所有姓名的包含B、且姓名為女(1)、且年齡大于24歲的員工資訊
@Test
void testSelectList1() {
QueryWrapper<Employee> queryWrapper = new QueryWrapper<>();
queryWrapper
.like("last_name","B")
.eq("gender",1)
.gt("age",24);
List<Employee> employees = employeeMapper.selectList(queryWrapper);
employees.forEach(System.out::println);
}
需求描述:查詢所有員工資訊
@Test
void testSelectList2() {
List<Employee> employees = employeeMapper.selectList(null);
employees.forEach(System.out::println);
}
需求描述:查詢所有女生的數量(1)
@Test
void testSelectList3() {
QueryWrapper<Employee> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("gender", 1);
Integer count = employeeMapper.selectCount(queryWrapper);
System.out.println(count);
}
4.3.2、帶條件的修改
需求資訊:將年齡大于25歲的女生(1)的性別修改為男生(0)
@Test
void testUpdate() {
UpdateWrapper<Employee> updateWrapper = new UpdateWrapper<>();
updateWrapper
.eq("gender", 1)
.gt("age", 25)
;
Employee employee = new Employee();
employee.setGender(0);
employeeMapper.update(employee, updateWrapper);
}
4.3.3、帶條件的洗掉
需求資訊:將姓名帶有“Tom”的員工資訊洗掉
@Test
void testDelete() {
QueryWrapper<Employee> queryWrapper = new QueryWrapper<>();
queryWrapper.like("last_name", "Tom");
int result = employeeMapper.delete(queryWrapper);
System.out.println(result);
}
4.4、構造器使用(2)
引數說明:
- 以下出現的第一個入參
boolean condition表示該條件是否加入最后生成的sql中 - 以下代碼塊內的多個方法均為從上往下補全個別
boolean型別的入參,默認為true - 以下出現的泛型
Param均為Wrapper的子類實體(均具有AbstractWrapper的所有方法) - 以下方法在入參中出現的
R為泛型,在普通wrapper中是String,在LambdaWrapper中是函式(例:Entity::getId,Entity為物體類,getId為欄位id的getMethod) - 以下方法入參中的
R column均表示資料庫欄位,當R具體型別為String時則為資料庫欄位名(欄位名是資料庫關鍵字的自己用轉義符包裹)!而不是物體類資料欄位名,另當R具體型別為SFunction時專案runtime不支持eclipse自家的編譯器 - 以下舉例均為使用普通wrapper,入參為
Map和List的均以json形式表現 - 使用中如果入參的
Map或者List為空,則不會加入最后生成的sql中
AbstractWrapper:
說明:AbstractWrapper 是 QueryWrapper(LambdaQueryWrapper) 和 UpdateWrapper(LambdaUpdateWrapper) 的父類用于生成 sql 的 where 條件,entity 屬性也用于生成 sql 的 where 條件,注意 entity 生成的 where 條件與使用各個 api 生成的 where 條件沒有任何關聯行為
4.4.1、allEq
allEq(Map<R, V> params)
allEq(Map<R, V> params, boolean null2IsNull)
allEq(boolean condition, Map<R, V> params, boolean null2IsNull)
- 全部
eq(或個別isNull)
個別引數說明:
params:key為資料庫欄位名,value為欄位值
null2IsNull:為true則在map的value為null時呼叫 isNull方法,為false時則忽略value為null的
- 例1:
allEq({id:1,name:"老王",age:null})—>id = 1 and name = '老王' and age is null - 例2:
allEq({id:1,name:"老王",age:null}, false)—>id = 1 and name = '老王'
allEq(BiPredicate<R, V> filter, Map<R, V> params)
allEq(BiPredicate<R, V> filter, Map<R, V> params, boolean null2IsNull)
allEq(boolean condition, BiPredicate<R, V> filter, Map<R, V> params, boolean null2IsNull)
個別引數說明:
filter : 過濾函式,是否允許欄位傳入比對條件中
params 與 null2IsNull : 同上
- 例1:
allEq((k,v) -> k.indexOf("a") >= 0, {id:1,name:"老王",age:null})—>name = '老王' and age is null - 例2:
allEq((k,v) -> k.indexOf("a") >= 0, {id:1,name:"老王",age:null}, false)—>name = '老王'
4.4.2、eq
eq(R column, Object val)
eq(boolean condition, R column, Object val)
- 等于 =
- 例:
eq("name", "老王")—>name = '老王'
4.4.3、ne
ne(R column, Object val)
ne(boolean condition, R column, Object val)
- 不等于 <>
- 例:
ne("name", "老王")—>name <> '老王'
4.4.4、gt
gt(R column, Object val)
gt(boolean condition, R column, Object val)
- 大于 >
- 例:
gt("age", 18)—>age > 18
4.4.5、ge
ge(R column, Object val)
ge(boolean condition, R column, Object val)
- 大于等于 >=
- 例:
ge("age", 18)—>age >= 18
4.4.6、lt
lt(R column, Object val)
lt(boolean condition, R column, Object val)
- 小于 <
- 例:
lt("age", 18)—>age < 18
4.4.7、le
le(R column, Object val)
le(boolean condition, R column, Object val)
- 小于等于 <=
- 例:
le("age", 18)—>age <= 18
4.4.8、between
between(R column, Object val1, Object val2)
between(boolean condition, R column, Object val1, Object val2)
- BETWEEN 值1 AND 值2
- 例:
between("age", 18, 30)—>age between 18 and 30
4.4.9、notBetween
notBetween(R column, Object val1, Object val2)
notBetween(boolean condition, R column, Object val1, Object val2)
- NOT BETWEEN 值1 AND 值2
- 例:
notBetween("age", 18, 30)—>age not between 18 and 30
4.4.10、like
like(R column, Object val)
like(boolean condition, R column, Object val)
- LIKE ‘%值%’
- 例:
like("name", "王")—>name like '%王%'
4.4.11、notLike
notLike(R column, Object val)
notLike(boolean condition, R column, Object val)
- NOT LIKE ‘%值%’
- 例:
notLike("name", "王")—>name not like '%王%'
4.4.12、likeLeft
likeLeft(R column, Object val)
likeLeft(boolean condition, R column, Object val)
- LIKE ‘%值’
- 例:
likeLeft("name", "王")—>name like '%王'
4.4.13、likeRight
likeRight(R column, Object val)
likeRight(boolean condition, R column, Object val)
- LIKE ‘值%’
- 例:
likeRight("name", "王")—>name like '王%'
4.4.14、isNull
isNull(R column)
isNull(boolean condition, R column)
- 欄位 IS NULL
- 例:
isNull("name")—>name is null
4.4.15、isNotNull
isNotNull(R column)
isNotNull(boolean condition, R column)
- 欄位 IS NOT NULL
- 例:
isNotNull("name")—>name is not null
4.4.16、in
in(R column, Collection<?> value)
in(boolean condition, R column, Collection<?> value)
- 欄位 IN (value.get(0), value.get(1), …)
- 例:
in("age",{1,2,3})—>age in (1,2,3)
in(R column, Object... values)
in(boolean condition, R column, Object... values)
- 欄位 IN (v0, v1, …)
- 例:
in("age", 1, 2, 3)—>age in (1,2,3)
4.4.17、notIn
notIn(R column, Collection<?> value)
notIn(boolean condition, R column, Collection<?> value)
- 欄位 NOT IN (value.get(0), value.get(1), …)
- 例:
notIn("age",{1,2,3})—>age not in (1,2,3)
notIn(R column, Object... values)
notIn(boolean condition, R column, Object... values)
- 欄位 NOT IN (v0, v1, …)
- 例:
notIn("age", 1, 2, 3)—>age not in (1,2,3)
4.4.18、inSql
inSql(R column, String inValue)
inSql(boolean condition, R column, String inValue)
- 欄位 IN ( sql陳述句 )
- 例:
inSql("age", "1,2,3,4,5,6")—>age in (1,2,3,4,5,6) - 例:
inSql("id", "select id from table where id < 3")—>id in (select id from table where id < 3)
4.4.19、notInSql
notInSql(R column, String inValue)
notInSql(boolean condition, R column, String inValue)
- 欄位 NOT IN ( sql陳述句 )
- 例:
notInSql("age", "1,2,3,4,5,6")—>age not in (1,2,3,4,5,6) - 例:
notInSql("id", "select id from table where id < 3")—>id not in (select id from table where id < 3)
4.4.20、groupBy
groupBy(R... columns)
groupBy(boolean condition, R... columns)
- 分組:GROUP BY 欄位, …
- 例:
groupBy("id", "name")—>group by id,name
4.4.21、orderByAsc
orderByAsc(R... columns)
orderByAsc(boolean condition, R... columns)
- 排序:ORDER BY 欄位, … ASC
- 例:
orderByAsc("id", "name")—>order by id ASC,name ASC
4.4.22、orderByDesc
orderByDesc(R... columns)
orderByDesc(boolean condition, R... columns)
- 排序:ORDER BY 欄位, … DESC
- 例:
orderByDesc("id", "name")—>order by id DESC,name DESC
4.4.23、orderBy
orderBy(boolean condition, boolean isAsc, R... columns)
- 排序:ORDER BY 欄位, …
- 例:
orderBy(true, true, "id", "name")—>order by id ASC,name ASC
4.4.24、having
having(String sqlHaving, Object... params)
having(boolean condition, String sqlHaving, Object... params)
- HAVING ( sql陳述句 )
- 例:
having("sum(age) > 10")—>having sum(age) > 10 - 例:
having("sum(age) > {0}", 11)—>having sum(age) > 11
4.4.25、func
func(Consumer<Children> consumer)
func(boolean condition, Consumer<Children> consumer)
- func 方法(主要方便在出現if…else下呼叫不同方法能不斷鏈)
- 例:
func(i -> if(true) {i.eq("id", 1)} else {i.ne("id", 1)})
4.4.26、or
or()
or(boolean condition)
- 拼接 OR
注意事項:
主動呼叫or表示緊接著下一個方法不是用and連接!(不呼叫or則默認為使用and連接)
- 例:
eq("id",1).or().eq("name","老王")—>id = 1 or name = '老王'
or(Consumer<Param> consumer)
or(boolean condition, Consumer<Param> consumer)
- OR 嵌套
- 例:
or(i -> i.eq("name", "李白").ne("status", "活著"))—>or (name = '李白' and status <> '活著')
4.4.27、and
and(Consumer<Param> consumer)
and(boolean condition, Consumer<Param> consumer)
- AND 嵌套
- 例:
and(i -> i.eq("name", "李白").ne("status", "活著"))—>and (name = '李白' and status <> '活著')
4.4.28、nested
nested(Consumer<Param> consumer)
nested(boolean condition, Consumer<Param> consumer)
- 正常嵌套 不帶 AND 或者 OR
- 例:
nested(i -> i.eq("name", "李白").ne("status", "活著"))—>(name = '李白' and status <> '活著')
4.4.29、apply
apply(String applySql, Object... params)
apply(boolean condition, String applySql, Object... params)
- 拼接 sql
注意事項:
該方法可用于資料庫函式動態入參的params對應前面applySql內部的{index}部分,這樣是不會有sql注入風險的,反之會有!
- 例:
apply("id = 1")—>id = 1 - 例:
apply("date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")—>date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'") - 例:
apply("date_format(dateColumn,'%Y-%m-%d') = {0}", "2008-08-08")—>date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")
4.4.30、last
last(String lastSql)
last(boolean condition, String lastSql)
- 無視優化規則直接拼接到 sql 的最后
注意事項:
只能呼叫一次,多次呼叫以最后一次為準,有sql注入的風險,請謹慎使用
- 例:
last("limit 1")
4.4.31、exists
exists(String existsSql)
exists(boolean condition, String existsSql)
- 拼接 EXISTS ( sql陳述句 )
- 例:
exists("select id from table where age = 1")—>exists (select id from table where age = 1)
4.4.32、notExists
notExists(String notExistsSql)
notExists(boolean condition, String notExistsSql)
- 拼接 NOT EXISTS ( sql陳述句 )
- 例:
notExists("select id from table where age = 1")—>not exists (select id from table where age = 1)
第五章 MyBatis-Plus3代碼生成器
5.1、資料匯入
## 洗掉表
DROP TABLE IF EXISTS `tbl_user`;
## 創建表
CREATE TABLE `tbl_user` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主鍵ID',
`name` VARCHAR(30) DEFAULT NULL COMMENT '姓名',
`age` INT(11) DEFAULT NULL COMMENT '年齡',
`email` VARCHAR(30) DEFAULT NULL COMMENT '郵箱',
PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COMMENT='用戶';
## 匯入資料
INSERT INTO `tbl_user`(`id`,`name`,`age`,`email`) VALUES (1,'Jone',18,'test1@baomidou.com');
INSERT INTO `tbl_user`(`id`,`name`,`age`,`email`) VALUES (2,'Jack',20,'test2@baomidou.com');
INSERT INTO `tbl_user`(`id`,`name`,`age`,`email`) VALUES (3,'Tom',28,'test3@baomidou.com');
INSERT INTO `tbl_user`(`id`,`name`,`age`,`email`) VALUES (4,'Sandy',21,'test4@baomidou.com');
INSERT INTO `tbl_user`(`id`,`name`,`age`,`email`) VALUES (5,'Billie',24,'test5@baomidou.com');
5.2、代碼生成器簡介
AutoGenerator 是 MyBatis-Plus 的代碼生成器,通過 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各個模塊的代碼,極大的提升了開發效率,
5.3、代碼生成器使用
5.3.1、添加依賴
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<!-- 插件管理 -->
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
</plugin>
</plugins>
<!-- 資源管理 -->
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.conf</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.conf</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
5.3.2、添加配置
application.properties
#server
server.port=8080
#mysql
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mp?useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=123456
#mybatis-plus
mybatis-plus.mapper-locations=classpath*:**/mapper/xml/*.xml
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
5.3.3、啟動配置
MpDemoApplication.java
@SpringBootApplication
@MapperScan("com.caochenlei.mpdemo.mapper")
public class MpDemoApplication {
public static void main(String[] args) {
SpringApplication.run(MpDemoApplication.class, args);
}
}
5.3.4、代碼生成
CodeGenerator.java
public class CodeGenerator {
public static String scanner(String tip) {
Scanner scanner = new Scanner(System.in);
StringBuilder help = new StringBuilder();
help.append("請輸入" + tip + ":");
System.out.println(help.toString());
if (scanner.hasNext()) {
String ipt = scanner.next();
if (StringUtils.isNotBlank(ipt)) {
return ipt;
}
}
throw new MybatisPlusException("請輸入正確的" + tip + "!");
}
public static void main(String[] args) {
// 代碼生成器
AutoGenerator mpg = new AutoGenerator();
// 全域配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
gc.setOutputDir(projectPath + "/src/main/java");//設定代碼生成路徑
gc.setFileOverride(true);//是否覆寫以前檔案
gc.setOpen(false);//是否打開生成目錄
gc.setAuthor("caochenlei");//設定專案作者名稱
gc.setIdType(IdType.AUTO);//設定主鍵策略
gc.setBaseResultMap(true);//生成基本ResultMap
gc.setBaseColumnList(true);//生成基本ColumnList
gc.setServiceName("%sService");//去掉服務默認前綴
mpg.setGlobalConfig(gc);
// 資料源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://localhost:3306/mp?useSSL=false&useUnicode=true&characterEncoding=utf8");
dsc.setDriverName("com.mysql.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("123456");
mpg.setDataSource(dsc);
// 包配置
PackageConfig pc = new PackageConfig();
pc.setParent("com.caochenlei.mpdemo");
pc.setMapper("mapper");
pc.setXml("mapper.xml");
pc.setEntity("pojo");
pc.setService("service");
pc.setServiceImpl("service.impl");
pc.setController("controller");
mpg.setPackageInfo(pc);
// 策略配置
StrategyConfig sc = new StrategyConfig();
sc.setNaming(NamingStrategy.underline_to_camel);
sc.setColumnNaming(NamingStrategy.underline_to_camel);
sc.setEntityLombokModel(true);
sc.setRestControllerStyle(true);
sc.setControllerMappingHyphenStyle(true);
sc.setTablePrefix("tbl_");
sc.setInclude(scanner("表名,多個英文逗號分割").split(","));
mpg.setStrategy(sc);
// 生成代碼
mpg.execute();
}
}
5.3.5、工程結構

5.3.6、添加代碼
UserController.java
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/all")
public List<User> getAll() {
return userService.list();
}
}
5.3.7、啟動運行
MpDemoApplication.java 中運行主方法以此來啟動整個工程
@SpringBootApplication
@MapperScan("com.caochenlei.mpdemo.mapper")
public class MpDemoApplication {
public static void main(String[] args) {
SpringApplication.run(MpDemoApplication.class, args);
}
}
5.3.8、測驗方法
使用瀏覽器打開:http://localhost:8080/user/all

5.3.9、溫馨提示
需要Lombok插件支持,只需要安裝一下就可以了,打開 IDEA,進入 File -> Settings -> Plugins,安裝完成后重啟

5.4、代碼生成器方法
通用 Service CRUD 封裝 IService 介面,進一步封裝 CRUD 采用 get 查詢單行 remove 洗掉 list 查詢集合 page 分頁 前綴命名方式區分 Mapper 層避免混淆,泛型 T 為任意物體物件,建議如果存在自定義通用 Service 方法的可能,請創建自己的 IBaseService 繼承 Mybatis-Plus 提供的基類,物件 Wrapper 為 條件構造器,
5.4.1、save
// 插入一條記錄(選擇欄位,策略插入)
boolean save(T entity);
// 插入(批量)
boolean saveBatch(Collection<T> entityList);
// 插入(批量)
boolean saveBatch(Collection<T> entityList, int batchSize);
引數說明:
| 型別 | 引數名 | 描述 |
|---|---|---|
| T | entity | 物體物件 |
| Collection<T> | entityList | 物體物件集合 |
| int | batchSize | 插入批次數量 |
5.4.2、saveOrUpdate
// TableId 注解存在更新記錄,否插入一條記錄
boolean saveOrUpdate(T entity);
// 根據updateWrapper嘗試更新,否繼續執行saveOrUpdate(T)方法
boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);
引數說明:
| 型別 | 引數名 | 描述 |
|---|---|---|
| T | entity | 物體物件 |
| Wrapper<T> | updateWrapper | 物體物件封裝操作類 UpdateWrapper |
| Collection<T> | entityList | 物體物件集合 |
| int | batchSize | 插入批次數量 |
5.4.3、remove
// 根據 entity 條件,洗掉記錄
boolean remove(Wrapper<T> queryWrapper);
// 根據 ID 洗掉
boolean removeById(Serializable id);
// 根據 columnMap 條件,洗掉記錄
boolean removeByMap(Map<String, Object> columnMap);
// 洗掉(根據ID 批量洗掉)
boolean removeByIds(Collection<? extends Serializable> idList);
引數說明:
| 型別 | 引數名 | 描述 |
|---|---|---|
| Wrapper<T> | queryWrapper | 物體包裝類 QueryWrapper |
| Serializable | id | 主鍵ID |
| Map<String, Object> | columnMap | 表欄位 map 物件 |
| Collection<? extends Serializable> | idList | 主鍵ID串列 |
5.4.4、update
// 根據 UpdateWrapper 條件,更新記錄 需要設定sqlset
boolean update(Wrapper<T> updateWrapper);
// 根據 whereEntity 條件,更新記錄
boolean update(T entity, Wrapper<T> updateWrapper);
// 根據 ID 選擇修改
boolean updateById(T entity);
// 根據ID 批量更新
boolean updateBatchById(Collection<T> entityList);
// 根據ID 批量更新
boolean updateBatchById(Collection<T> entityList, int batchSize);
引數說明:
| 型別 | 引數名 | 描述 |
|---|---|---|
| Wrapper<T> | updateWrapper | 物體物件封裝操作類 UpdateWrapper |
| T | entity | 物體物件 |
| Collection<T> | entityList | 物體物件集合 |
| int | batchSize | 更新批次數量 |
5.4.5、get
// 根據 ID 查詢
T getById(Serializable id);
// 根據 Wrapper,查詢一條記錄,結果集,如果是多個會拋出例外,隨機取一條加上限制條件 wrapper.last("LIMIT 1")
T getOne(Wrapper<T> queryWrapper);
// 根據 Wrapper,查詢一條記錄
T getOne(Wrapper<T> queryWrapper, boolean throwEx);
// 根據 Wrapper,查詢一條記錄
Map<String, Object> getMap(Wrapper<T> queryWrapper);
// 根據 Wrapper,查詢一條記錄
<V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);
引數說明:
| 型別 | 引數名 | 描述 |
|---|---|---|
| Serializable | id | 主鍵ID |
| Wrapper<T> | queryWrapper | 物體物件封裝操作類 QueryWrapper |
| boolean | throwEx | 有多個 result 是否拋出例外 |
| T | entity | 物體物件 |
| Function<? super Object, V> | mapper | 轉換函式 |
5.4.6、list
// 查詢所有
List<T> list();
// 查詢串列
List<T> list(Wrapper<T> queryWrapper);
// 查詢(根據ID 批量查詢)
Collection<T> listByIds(Collection<? extends Serializable> idList);
// 查詢(根據 columnMap 條件)
Collection<T> listByMap(Map<String, Object> columnMap);
// 查詢所有串列
List<Map<String, Object>> listMaps();
// 查詢串列
List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper);
// 查詢全部記錄
List<Object> listObjs();
// 查詢全部記錄
<V> List<V> listObjs(Function<? super Object, V> mapper);
// 根據 Wrapper 條件,查詢全部記錄
List<Object> listObjs(Wrapper<T> queryWrapper);
// 根據 Wrapper 條件,查詢全部記錄
<V> List<V> listObjs(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);
引數說明:
| 型別 | 引數名 | 描述 |
|---|---|---|
| Wrapper<T> | queryWrapper | 物體物件封裝操作類 QueryWrapper |
| Collection<? extends Serializable> | idList | 主鍵ID串列 |
| Map<?String, Object> | columnMap | 表欄位 map 物件 |
| Function<? super Object, V> | mapper | 轉換函式 |
5.4.7、page
// 無條件分頁查詢
IPage<T> page(IPage<T> page);
// 條件分頁查詢
IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);
// 無條件分頁查詢
IPage<Map<String, Object>> pageMaps(IPage<T> page);
// 條件分頁查詢
IPage<Map<String, Object>> pageMaps(IPage<T> page, Wrapper<T> queryWrapper);
引數說明:
| 型別 | 引數名 | 描述 |
|---|---|---|
| IPage<T> | page | 翻頁物件 |
| Wrapper<T> | queryWrapper | 物體物件封裝操作類 QueryWrapper |
5.4.8、count
// 查詢總記錄數
int count();
// 根據 Wrapper 條件,查詢總記錄數
int count(Wrapper<T> queryWrapper);
引數說明:
| 型別 | 引數名 | 描述 |
|---|---|---|
| Wrapper<T> | queryWrapper | 物體物件封裝操作類 QueryWrapper |
5.4.9、chain
query
// 鏈式查詢 普通
QueryChainWrapper<T> query();
// 鏈式查詢 lambda 式,注意:不支持 Kotlin
LambdaQueryChainWrapper<T> lambdaQuery();
// 示例:
query().eq("column", value).one();
lambdaQuery().eq(Entity::getId, value).list();
update
// 鏈式更改 普通
UpdateChainWrapper<T> update();
// 鏈式更改 lambda 式,注意:不支持 Kotlin
LambdaUpdateChainWrapper<T> lambdaUpdate();
// 示例:
update().eq("column", value).remove();
lambdaUpdate().eq(Entity::getId, value).update(entity);
第六章 MyBatis-Plus3配置詳解
6.1、配置概述
本文講解了MyBatis-Plus在使用程序中的配置選項,其中部分配置繼承自MyBatis原生所支持的配置,
6.2、配置方式
-
Spring Boot:
-
application.properties(本文采用)
mybatis-plus.mapper-locations=classpath*:**/mapper/xml/*.xml mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl ...... -
application.yaml(推薦使用)
mybatis-plus: ...... configuration: ...... global-config: ...... db-config: ......
-
-
Spring MVC:
-
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean"> <property name="configuration" ref="configuration"/> <!-- 非必須 --> <property name="globalConfig" ref="globalConfig"/> <!-- 非必須 --> ...... </bean> <bean id="configuration" class="com.baomidou.mybatisplus.core.MybatisConfiguration"> ...... </bean> <bean id="globalConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig"> <property name="dbConfig" ref="dbConfig"/> <!-- 非必須 --> ...... </bean> <bean id="dbConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig.DbConfig"> ...... </bean>
-
6.3、配置選項
6.3.1、mapperLocations
- 型別:
String[] - 默認值:
["classpath*:/mapper/**/*.xml"]
MyBatis Mapper 所對應的 XML 檔案位置,如果您在 Mapper 中有自定義方法(XML 中有自定義實作),需要進行該配置,告訴 Mapper 所對應的 XML 檔案位置,Maven 多模塊專案的掃描路徑需以 classpath*: 開頭 (即加載多個 jar 包下的 XML 檔案),
mybatis-plus.mapper-locations=classpath*:**/mapper/xml/*.xml
6.3.2、typeAliasesPackage
- 型別:
String - 默認值:
null
MyBaits 別名包掃描路徑,通過該屬性可以給包中的類注冊別名,注冊后在 Mapper 對應的 XML 檔案中可以直接使用類名,而不用使用全限定的類名(即 XML 中呼叫的時候不用包含包名),
mybatis-plus.type-aliases-package=com.caochenlei.mpdemo.pojo
6.3.3、typeHandlersPackage
- 型別:
String - 默認值:
null
TypeHandler 掃描路徑,如果配置了該屬性,SqlSessionFactoryBean 會把該包下面的類注冊為對應的 TypeHandler,TypeHandler 通常用于自定義型別轉換,
mybatis-plus.type-handlers-package=com.caochenlei.mpdemo.type
6.3.4、typeEnumsPackage
- 型別:
String - 默認值:
null
列舉類 掃描路徑,如果配置了該屬性,會將路徑下的列舉類進行注入,讓物體類欄位能夠簡單快捷的使用列舉屬性,
mybatis-plus.type-enums-package=com.caochenlei.mpdemo.myenum
6.3.5、checkConfigLocation
- 型別:
boolean - 默認值:
false
啟動時是否檢查 MyBatis XML 檔案的存在,默認不檢查,
mybatis-plus.check-config-location=false
6.3.6、executorType
- 型別:
ExecutorType - 默認值:
simple
通過該屬性可指定 MyBatis 的執行器,MyBatis 的執行器總共有三種:
- ExecutorType.SIMPLE:該執行器型別不做特殊的事情,為每個陳述句的執行創建一個新的預處理陳述句(PreparedStatement)
- ExecutorType.REUSE:該執行器型別會復用預處理陳述句(PreparedStatement)
- ExecutorType.BATCH:該執行器型別會批量執行所有的更新陳述句
mybatis-plus.executor-type=simple
6.3.7、configurationProperties
- 型別:
Properties - 默認值:
null
指定外部化 MyBatis Properties 配置,通過該配置可以抽離配置,實作不同環境的配置部署,
6.3.8、configuration
- 型別:
Configuration - 默認值:
null
原生 MyBatis 所支持的配置,本部分(Configuration)的配置大都為 MyBatis 原生支持的配置,這意味著您可以通過 MyBatis XML 組態檔的形式進行配置,
6.3.8.1、mapUnderscoreToCamelCase
- 型別:
boolean - 默認值:
true
是否開啟自動駝峰命名規則(camel case)映射,即從經典資料庫列名 A_COLUMN(下劃線命名) 到經典 Java 屬性名 aColumn(駝峰命名) 的類似映射,此屬性在 MyBatis 中原默認值為 false,在 MyBatis-Plus 中,此屬性也將用于生成最終的 SQL 的 select body,如果您的資料庫命名符合規則無需使用 @TableField 注解指定資料庫欄位名,
mybatis-plus.configuration.map-underscore-to-camel-case=true
6.3.8.2、defaultEnumTypeHandler
- 型別:
Class<? extends TypeHandler - 默認值:
org.apache.ibatis.type.EnumTypeHandler
默認列舉處理類,如果配置了該屬性,列舉將統一使用指定處理器進行處理,
需要注意,它的取值可以有以下幾種,可以使用內置,也可以自定義:
- org.apache.ibatis.type.EnumTypeHandler : 存盤列舉的名稱
- org.apache.ibatis.type.EnumOrdinalTypeHandler : 存盤列舉的索引
- com.baomidou.mybatisplus.extension.handlers.MybatisEnumTypeHandler : 列舉類需要實作IEnum介面或欄位標記@EnumValue注解.(3.1.2以下版本為EnumTypeHandler)
mybatis-plus.configuration.default-enum-type-handler=org.apache.ibatis.type.EnumTypeHandler
6.3.8.3、aggressiveLazyLoading
- 型別:
boolean - 默認值:
true
當設定為 true 的時候,懶加載的物件可能被任何懶屬性全部加載,否則,每個屬性都按需加載,需要和 lazyLoadingEnabled 一起使用,
mybatis-plus.configuration.aggressive-lazy-loading=true
mybatis-plus.configuration.lazy-loading-enabled=true
6.3.8.4、autoMappingBehavior
- 型別:
AutoMappingBehavior - 默認值:
partial
MyBatis 自動映射策略,通過該配置可指定 MyBatis 是否并且如何來自動映射資料表欄位與物件的屬性,總共有 3 種可選值:
- AutoMappingBehavior.NONE:不啟用自動映射
- AutoMappingBehavior.PARTIAL:只對非嵌套的 resultMap 進行自動映射
- AutoMappingBehavior.FULL:對所有的 resultMap 都進行自動映射
mybatis-plus.configuration.auto-mapping-behavior=partial
6.3.8.5、autoMappingUnknownColumnBehavior
- 型別:
AutoMappingUnknownColumnBehavior - 默認值:
NONE
MyBatis 自動映射時未知列或未知屬性處理策略,通過該配置可指定 MyBatis 在自動映射程序中遇到未知列或者未知屬性時如何處理,總共有 3 種可選值:
- AutoMappingUnknownColumnBehavior.NONE:不做任何處理 (默認值)
- AutoMappingUnknownColumnBehavior.WARNING:以日志的形式列印相關警告資訊
- AutoMappingUnknownColumnBehavior.FAILING:當作映射失敗處理,并拋出例外和詳細資訊
mybatis-plus.configuration.auto-mapping-unknown-column-behavior=none
6.3.8.6、localCacheScope
- 型別:
String - 默認值:
SESSION
Mybatis一級快取,默認為 SESSION,
- SESSION:session級別快取,同一個session相同查詢陳述句不會再次查詢資料庫
- STATEMENT:關閉一級快取
單服務架構中(有且僅有只有一個程式提供相同服務),一級快取開啟不會影響業務,只會提高性能, 微服務架構中需要關閉一級快取,原因:Service1先查詢資料,若之后Service2修改了資料,之后Service1又再次以同樣的查詢條件查詢資料,因走快取會出現查處的資料不是最新資料,
mybatis-plus.configuration.local-cache-scope=session
6.3.8.7、cacheEnabled
- 型別:
boolean - 默認值:
true
開啟Mybatis二級快取,默認為 true,
mybatis-plus.configuration.cache-enabled=true
6.3.8.8、callSettersOnNulls
- 型別:
boolean - 默認值:
false
指定當結果集中值為 null 的時候是否呼叫映射物件的 Setter(Map 物件時為 put)方法,通常運用于有 Map.keySet() 依賴或 null 值初始化的情況,
通俗的講,即 MyBatis 在使用 resultMap 來映射查詢結果中的列,如果查詢結果中包含空值的列,則 MyBatis 在映射的時候,不會映射這個欄位,這就導致在呼叫到該欄位的時候由于沒有映射,取不到而報空指標例外,
當您遇到類似的情況,請針對該屬性進行相關配置以解決以上問題,
注意:基本型別(int、boolean 等)是不能設定成 null 的,
mybatis-plus.configuration.call-setters-on-nulls=false
6.3.8.9、configurationFactory
- 型別:
Class<?> - 默認值:
null
指定一個提供 Configuration 實體的工廠類,該工廠生產的實體將用來加載已經被反序列化物件的懶加載屬性值,其必須包含一個簽名方法static Configuration getConfiguration(),(從 3.2.3 版本開始)
mybatis-plus.configuration.configuration-factory=
6.3.8.10、MyBatis3的配置屬性
這里只列出 MyBatis3 的 settings 標簽的屬性,更多配置,請自行探索!
我們這里以日志列印為例,一般使用駝峰命名對應 “ - ”
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
| 設定 | 描述 | 取值 | 默認值 |
|---|---|---|---|
| cacheEnabled | 該配置是影響所有映射器中配置快取的全域開關, | true | false | true |
| lazyLoadingEnabled | 該配置是延遲加載的全域開關,當開啟時,所有關聯物件都會延遲加載,在特定關聯關系中可通過設定 fetchType 屬性來覆寫該項的開關狀態, | true | false | false |
| aggressiveLazyLoading | 當啟用時,對任意延遲屬性的呼叫會使帶有延遲加載屬性的物件完整加載,反之,每種屬性將會按需加載, | true | false | false (true in ≤3.4.1) |
| multipleResultSetsEnabled | 是否允許單一陳述句回傳多結果集,需要兼容驅動, | true | false | true |
| useColumnLabel | 使用列標簽代替列名,不同的驅動會有不同的表現,具體可參考相關驅動檔案或通過測驗這兩種不同的模式來觀察所用驅動的結果, | true | false | true |
| useGeneratedKeys | 允許JDBC 支持自動生成主鍵,需要驅動兼容,如果設定為 true,則這個設定強制使用自動生成主鍵,盡管一些驅動不能兼容但仍可正常作業(比如 Derby), | true | false | false |
| autoMappingBehavior | 指定 MyBatis 應如何自動映射列到欄位或屬性, NONE:表示取消自動映射, PARTIAL:表示只會自動映射,沒有定義嵌套結果集和映射結果集, FULL:表示會自動映射任意復雜的結果集,無論是否嵌套, | NONE PARTIAL FULL | PARTIAL |
| autoMappingUnknownColumnBehavior | 指定自動映射當中未知列(或未知屬性型別)時的行為, 默認是不處理,只有當日志級別達到 WARN 級別或者以下,才會顯示相關日志,如果處理失敗會拋出 SqlSessionException例外, | NONE WARNING FAILING | NONE |
| defaultExecutorType | 配置默認的執行器, SIMPLE:是普通的執行器, REUSE:會重用預處理陳述句, BATCH:執行器將重用陳述句并執行批量更新, | SIMPLE REUSE BATCH | SIMPLE |
| defaultStatementTimeout | 設定超時時間,它決定驅動等待資料庫回應的秒數, | 任意正整數值 | Not Set (null) |
| defaultFetchSize | 設定資料庫驅動程式默認回傳的條數限制,此引數可以重新設定, | 任意正整數值 | Not Set (null) |
| defaultResultSetType | 指定按陳述句設定忽略它的滾動策略,(Since: 3.5.2) | FORWARD_ONLY SCROLL_SENSITIVE SCROLL_INSENSITIVE DEFAULT (same behavior with ‘Not Set’) | Not Set (null) |
| safeRowBoundsEnabled | 允許在嵌套陳述句中使用分頁(RowBounds), 如果允許,設定 false, | true | false | false |
| safeResultHandlerEnabled | 允許在嵌套陳述句中使用分頁(ResultHandler), 如果允許,設定false | true | false | true |
| mapUnderscoreToCamelCaseEnables | 是否開啟自動駝峰命名規則映射,即從經典資料庫列名 A_COLUMN 到經典 Java 屬性名 aColumn 的類似映射, | true | false | false |
| localCacheScope | MyBatis 利用本地快取機制(Local Cache)防止回圈參考(circular references)和加速關聯復嵌套査詢, SESSION:這種情況下會快取一個會話中執行的所有查詢, STATEMENT:代表本地會話僅用在陳述句執行上,對相同 SqlScssion 的不同呼叫將不會共享資料, | SESSION | STATEMENT | SESSION |
| jdbcTypeForNull | 當沒有為引數提供特定的 JDBC 型別時,為空值時指定 JDBC 型別,某些驅動需要指定列的 JDBC 型別,多數情況直接用一般型別即可,比如 NULL、VARCHAR 或 OTHER, | JdbcType 列舉值 | OTHER |
| lazyLoadTriggerMethods | 指定哪個物件的方法觸發一次延遲加載, | 一個逗號分隔的方法名稱串列 | equals,clone, hashCode,toString |
| defaultScriptingLanguage | 指定動態 SQL 生成的默認語言, | 型別別名或指定類的全名稱 | org.apache. ibatis.scripting. xmltags.XMLLang |
| defaultEnumTypeHandler | 指定默認情況下用于列舉的TypeHandler,(Since: 3.4.5) | 型別別名或指定類的全名稱 | org.apache. ibatis.type. EnumTypeHandler |
| callSettersOnNulls | 指定當結果集中值為 null 時,是否呼叫映射物件的 setter(map 物件時為 put)方法,這對于 Map.keySet() 依賴或 null 值初始化時是有用的,注意,基本型別(int、boolean 等)不能設定成 null, | true | false | false |
| returnInstanceForEmptyRowMyBatis | 默認情況下,MyBatis在回傳行的所有列都為null時回傳null,啟用此設定后,MyBatis將回傳空實體,注意,它也適用于嵌套結果(即collectioin和association),(Since: 3.4.2) | true | false | false |
| logPrefix | 指定 MyBatis 增加到日志名稱的前綴, | 任何字串 | Not set |
| logImpl | 指定 MyBatis 所用日志的具體實作,未指定時將自動査找, | SLF4J LOG4J LOG4J2 JDK_LOGGING COMMONS_LOGGING STDOUT_LOGGING NO_LOGGING | Not set |
| proxyFactory | 指定 MyBatis 創建具有延遲加載能力的物件所用到的代理工具, | CGLIB | JAVASSIST | JAVASSIST (MyBatis 3.3 or above) |
| vfsImpl | 指定 VFS 的實作類, | 自定義VFS實作的類的全名稱,用逗號分隔, | Not set |
| useActualParamName | 允許使用方法簽名中的名稱作為陳述句引數名稱, 為了使用該特性,你的專案必須采用 Java 8 編譯,并且加上 -parameters 選項,(Since: 3.4.1) | true | false | true |
| configurationFactory | 指定提供配置實體的類,回傳的配置實體用于加載反序列化物件的惰性屬性,此類必須具有簽名靜態配置getConfiguration() 的方法,(Since: 3.2.3) | 型別別名或指定類的全名稱 | Not set |
| shrinkWhitespacesInSql | 從SQL中洗掉多余的空白字符,注意,這也會影響SQL中的文字字串,(Since 3.5.5) | true | false | false |
6.3.9、globalConfig
- 型別:
com.baomidou.mybatisplus.core.config.GlobalConfig - 默認值:
GlobalConfig::new
MyBatis-Plus 全域策略配置,
6.3.9.1、banner
- 型別:
boolean - 默認值:
true
是否控制臺 print mybatis-plus 的 LOGO,
mybatis-plus.global-config.banner=true
6.3.9.2、enableSqlRunner
- 型別:
boolean - 默認值:
false
是否初始化 SqlRunner(com.baomidou.mybatisplus.extension.toolkit.SqlRunner)
mybatis-plus.global-config.enable-sql-runner=false
6.3.9.3、superMapperClass
- 型別:
Class - 默認值:
com.baomidou.mybatisplus.core.mapper.Mapper.class
通用Mapper父類(影響sqlInjector,只有這個的子類的 mapper 才會注入 sqlInjector 內的 method)
mybatis-plus.global-config.super-mapper-class=com.baomidou.mybatisplus.core.mapper.Mapper
6.3.9.4、dbConfig
- 型別:
com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig - 默認值:
null
MyBatis-Plus 全域策略中的 DB 策略配置,
6.3.9.4.1、idType
- 型別:
com.baomidou.mybatisplus.annotation.IdType - 默認值:
ASSIGN_ID
全域默認主鍵型別,
mybatis-plus.global-config.db-config.id-type=assign_id
6.3.9.4.2、tablePrefix
- 型別:
String - 默認值:
null
表名前綴,
mybatis-plus.global-config.db-config.table-prefix=tbl_
6.3.9.4.3、schema
- 型別:
String - 默認值:
null
schema,
mybatis-plus.global-config.db-config.schema=
6.3.9.4.4、columnFormat
- 型別:
String - 默認值:
null
欄位 format,例: %s,(對主鍵無效)
mybatis-plus.global-config.db-config.column-format=
6.3.9.4.5、propertyFormat
- 型別:
String - 默認值:
null
entity 的欄位(property)的 format,只有在 column as property 這種情況下生效例: %s,(對主鍵無效)(since 3.3.0),
mybatis-plus.global-config.db-config.property-format=
6.3.9.4.6、tableUnderline
- 型別:
boolean - 默認值:
true
表名是否使用駝峰轉下劃線命名,只對表名生效,
mybatis-plus.global-config.db-config.table-underline=true
6.3.9.4.7、capitalMode
- 型別:
boolean - 默認值:
false
大寫命名,對表名和欄位名均生效,
mybatis-plus.global-config.db-config.capital-mode=false
6.3.9.4.8、logicDeleteField
- 型別:
String - 默認值:
null
全域的entity的邏輯洗掉欄位屬性名,(邏輯洗掉下有效)
mybatis-plus.global-config.db-config.logic-delete-field=
6.3.9.4.9、logicDeleteValue
- 型別:
String - 默認值:
1
邏輯已洗掉值,(邏輯洗掉下有效)
mybatis-plus.global-config.db-config.logic-delete-value=1
6.3.9.4.10、logicNotDeleteValue
- 型別:
String - 默認值:
0
邏輯未洗掉值,(邏輯洗掉下有效)
mybatis-plus.global-config.db-config.logic-not-delete-value=0
6.3.9.4.11、insertStrategy
- 型別:
com.baomidou.mybatisplus.annotation.FieldStrategy - 默認值:
NOT_NULL
欄位驗證策略之 insert,在 insert 的時候的欄位驗證策略,
mybatis-plus.global-config.db-config.insert-strategy=not_null
6.3.9.4.12、updateStrategy
- 型別:
com.baomidou.mybatisplus.annotation.FieldStrategy - 默認值:
NOT_NULL
欄位驗證策略之 update,在 update 的時候的欄位驗證策略,
mybatis-plus.global-config.db-config.update-strategy=not_null
6.3.9.4.13、selectStrategy
- 型別:
com.baomidou.mybatisplus.annotation.FieldStrategy - 默認值:
NOT_NULL
欄位驗證策略之 select,在 select 的時候的欄位驗證策略既 wrapper 根據內部 entity 生成的 where 條件,
mybatis-plus.global-config.db-config.select-strategy=not_null
6.4、配置小結
#mybatis-plus
mybatis-plus.mapper-locations=classpath*:**/mapper/xml/*.xml
mybatis-plus.type-aliases-package=com.caochenlei.mpdemo.pojo
mybatis-plus.type-handlers-package=com.caochenlei.mpdemo.type
mybatis-plus.type-enums-package=com.caochenlei.mpdemo.enum
mybatis-plus.check-config-location=false
mybatis-plus.executor-type=simple
#mybatis-plus.configuration
mybatis-plus.configuration.map-underscore-to-camel-case=true
mybatis-plus.configuration.default-enum-type-handler=org.apache.ibatis.type.EnumTypeHandler
mybatis-plus.configuration.aggressive-lazy-loading=true
mybatis-plus.configuration.lazy-loading-enabled=true
mybatis-plus.configuration.auto-mapping-behavior=partial
mybatis-plus.configuration.auto-mapping-unknown-column-behavior=none
mybatis-plus.configuration.local-cache-scope=session
mybatis-plus.configuration.cache-enabled=true
mybatis-plus.configuration.call-setters-on-nulls=false
mybatis-plus.configuration.configuration-factory=
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
#mybatis-plus.global-config
mybatis-plus.global-config.banner=true
mybatis-plus.global-config.enable-sql-runner=false
mybatis-plus.global-config.super-mapper-class=com.baomidou.mybatisplus.core.mapper.Mapper
#mybatis-plus.global-config.db-config
mybatis-plus.global-config.db-config.id-type=assign_id
mybatis-plus.global-config.db-config.table-prefix=tbl_
mybatis-plus.global-config.db-config.schema=
mybatis-plus.global-config.db-config.column-format=
mybatis-plus.global-config.db-config.property-format=
mybatis-plus.global-config.db-config.table-underline=true
mybatis-plus.global-config.db-config.capital-mode=false
mybatis-plus.global-config.db-config.logic-delete-field=
mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0
mybatis-plus.global-config.db-config.insert-strategy=not_null
mybatis-plus.global-config.db-config.update-strategy=not_null
mybatis-plus.global-config.db-config.select-strategy=not_null
第七章 MyBatis-Plus3插件擴展
創建包:com.caochenlei.mpdemo.config
新建類:com.caochenlei.mpdemo.config.MybatisPlusConfig
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
return interceptor;
}
}
7.1、分頁插件
插件功能:提供資料分頁功能,
添加插件:
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 添加分頁插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
屬性設定:
| 屬性名 | 型別 | 默認值 | 描述 |
|---|---|---|---|
| overflow | boolean | false | 溢位總頁數后是否進行處理(默認不處理,參見 插件#continuePage 方法) |
| maxLimit | Long | 單頁分頁條數限制(默認無限制,參見 插件#handlerLimit 方法) | |
| dbType | DbType | 資料庫型別(根據型別獲取應使用的分頁方言,參見 插件#findIDialect 方法) | |
| dialect | IDialect | 方言實作類(參見 插件#findIDialect 方法) |
測驗方法:
@Test
void testPagination() {
Page<Employee> page = new Page<>(1,5);
Page<Employee> employeePage = employeeMapper.selectPage(page, null);
employeePage.getRecords().forEach(System.out::println);
System.out.println("當前頁:" + employeePage.getCurrent());
System.out.println("總頁數:" + employeePage.getPages());
System.out.println("記錄數:" + employeePage.getTotal());
System.out.println("是否有上一頁:" + employeePage.hasPrevious());
System.out.println("是否有下一頁:" + employeePage.hasNext());
}
控制臺截圖:

資料庫截圖:

7.2、執行分析插件
插件功能:防止全表更新與全表洗掉,依次保護資料庫的安全,建議開發環境使用,不建議生產環境使用,
添加插件:
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 添加分頁插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
// 添加執行分析插件
interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
return interceptor;
}
}
測驗方法:
@Test
void testBlockAttack() {
int result = employeeMapper.delete(null);
System.out.println(result);
}
控制臺截圖:

資料庫截圖:

7.3、性能分析插件
插件功能:該功能依賴 p6spy 組件,完美的輸出列印 SQL 及執行時長, 3.1.0 以上版本支持,
添加依賴:
<dependency>
<groupId>p6spy</groupId>
<artifactId>p6spy</artifactId>
<version>3.9.1</version>
</dependency>
修改配置:application.properties
#mysql
#spring.datasource.driver-class-name=com.mysql.jdbc.Driver
#spring.datasource.url=jdbc:mysql://localhost:3306/mp?useUnicode=true&characterEncoding=utf8
#spring.datasource.username=root
#spring.datasource.password=123456
#p6spy
spring.datasource.driver-class-name=com.p6spy.engine.spy.P6SpyDriver
spring.datasource.url=jdbc:p6spy:mysql://localhost:3306/mp
spring.datasource.username=root
spring.datasource.password=123456
添加配置:spy.properties
# 3.2.1以上使用
modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory
# 自定義日志列印
logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
# 日志輸出到控制臺
appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
# 使用日志系統記錄 sql
#appender=com.p6spy.engine.spy.appender.Slf4JLogger
# 設定 p6spy driver 代理
deregisterdrivers=true
# 取消JDBC URL前綴
useprefix=true
# 配置記錄 Log 例外,可去掉的結果集有error,info,batch,debug,statement,commit,rollback,result,resultset.
excludecategories=info,debug,result,commit,resultset
# 日期格式
dateformat=yyyy-MM-dd HH:mm:ss
# 實際驅動可多個
driverlist=com.mysql.jdbc.Driver
# 是否開啟慢SQL記錄
outagedetection=true
# 慢SQL記錄標準 2 秒
outagedetectioninterval=2
注意問題:
- driver-class-name 為 p6spy 提供的驅動類
- url 前綴為 jdbc:p6spy 跟著冒號為對應資料庫連接地址
- 列印出sql為null,在excludecategories增加commit
- 批量操作不列印sql,去除excludecategories中的batch
- 批量操作列印重復的問題請使用MybatisPlusLogFactory (3.2.1新增)
- 該插件有性能損耗,不建議生產環境使用
添加插件:該插件不用添加自動集成
測驗方法:
@Test
void testPagination() {
Page<Employee> page = new Page<>(1,5);
Page<Employee> employeePage = employeeMapper.selectPage(page, null);
employeePage.getRecords().forEach(System.out::println);
System.out.println("當前頁:" + employeePage.getCurrent());
System.out.println("總頁數:" + employeePage.getPages());
System.out.println("記錄數:" + employeePage.getTotal());
System.out.println("是否有上一頁:" + employeePage.hasPrevious());
System.out.println("是否有下一頁:" + employeePage.hasNext());
}
控制臺截圖:

資料庫截圖:

7.4、樂觀鎖插件
插件功能:當要更新一條記錄的時候,希望這條記錄沒有被別人更新,可以使用樂觀鎖,MyBatis-Plus就提供了樂觀鎖插件,
實作方式:樂觀鎖實作方式如下
- 取出記錄時,獲取當前version
- 更新時,帶上這個version
- 執行更新時, set version = newVersion where version = oldVersion
- 如果version不對,就更新失敗
添加欄位:
-
資料庫:
ALTER TABLE `tbl_employee` ADD COLUMN `version` INT(11) DEFAULT '1' NULL AFTER `age`; -
物體類:
@Version private Integer version; public Integer getVersion() { return version; } public void setVersion(Integer version) { this.version = version; }
注意事項:
- 支持的資料型別只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime
- 整數型別下
newVersion = oldVersion + 1 newVersion會回寫到entity中- 僅支持
updateById(id)與update(entity, wrapper)方法 - 在
update(entity, wrapper)方法下,wrapper不能復用
添加插件:
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 添加分頁插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
// 添加執行分析插件
interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
// 添加樂觀鎖插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
測驗方法:
@Test
void testOptimisticLocker(){
Employee employee = employeeMapper.selectById(1);
employee.setLastName("Bob");
int result = employeeMapper.updateById(employee);
System.out.println(result);
}
控制臺截圖:

資料庫截圖:

7.5、快速開發插件
插件功能:可以通過介面方法名直接創建對應mapper中的sql標簽,還可以Mapper和xml可以來回跳,更多功能自行探索!
計劃支持:
- 連接資料源之后 xml 里自動提示欄位
- sql 增刪改查
- 集成 MP 代碼生成
- 其它
安裝方法:
需要MybatisX插件支持,只需要安裝一下就可以了,打開 IDEA,進入 File -> Settings -> Plugins,安裝完成后重啟

第八章 MyBatis-Plus3其它功能
8.1、Sql 注入器
根據 MybatisPlus 的 AutoSqlInjector 可以自定義各種你想要的 SQL 注入到全域中,相當于自定義 MybatisPlus 自動注入的方法,之前需要在 xml 中進行配置的 SQL 陳述句,現在通過擴展 AutoSqlInjector 在加載 mybatis 環境時就注入,
介面方法:然后在添加一個@Repository注解
UserMapper.java
@Repository
public interface UserMapper extends BaseMapper<User> {
public void deleteAll();
}
注意:我們不需要撰寫xml映射,因為我們會采用sql注入的形式,在 MybatisPlus 啟動的時候就注入,
創建物件:在該com.caochenlei.mpdemo.injector(沒有創建)包下創建MyMappedStatement.java、MySqlInjector.java
MyMappedStatement.java
public class MyMappedStatement extends AbstractMethod {
@Override
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
// 介面中的方法名
String method = "deleteAll";
// 該方法執行陳述句
String sql = "delete from " + tableInfo.getTableName();
// 創建SqlSource
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
// 構造一個洗掉的MappedStatement并回傳
return this.addDeleteMappedStatement(mapperClass, method, sqlSource);
}
}
MySqlInjector.java
public class MySqlInjector extends DefaultSqlInjector {
@Override
public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
List<AbstractMethod> methodList = super.getMethodList(mapperClass);
methodList.add(new MyMappedStatement());
return methodList;
}
}
注釋“執行分析插件”:會影響代碼執行,它會阻止全表洗掉操作,所以先注釋掉,反正我們已經學會了
MybatisPlusConfig.java
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 添加分頁插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
// 添加執行分析插件
//interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
// 添加樂觀鎖插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
添加“自定義SQL注入物件”:
MybatisPlusConfig.java
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 添加分頁插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
// 添加執行分析插件
//interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
// 添加樂觀鎖插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
@Bean
public MySqlInjector mySqlInjector() {
return new MySqlInjector();
}
}
測驗方法:
@Autowired
private UserMapper userMapper;
@Test
void testDeleteAll() {
userMapper.deleteAll();
}
控制臺截圖:沒有寫xml映射代碼,它也會執行洗掉,原因是我們在啟動的時候自動注入了

資料庫截圖:

8.2、邏輯洗掉
邏輯洗掉:資料洗掉并不會真正的從資料庫中將資料洗掉掉,而是將當前被洗掉的這條資料中的一個邏輯洗掉欄位置為洗掉狀態,
匯入資料:
## 洗掉表
DROP TABLE IF EXISTS `tbl_student`;
## 創建表
CREATE TABLE `tbl_student` (
`id` INT(11) NOT NULL AUTO_INCREMENT COMMENT '主鍵ID',
`name` VARCHAR(255) DEFAULT NULL COMMENT '學生姓名',
`age` INT(11) DEFAULT NULL COMMENT '學生年齡',
`grade` VARCHAR(255) DEFAULT NULL COMMENT '學生年紀',
`status` VARCHAR(255) DEFAULT NULL COMMENT '學生狀態',
`deleted` INT(11) DEFAULT '0' COMMENT '是否洗掉(0:未洗掉、1:已洗掉)',
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8 COMMENT='學生';
## 導入資料
INSERT INTO `tbl_student`(`id`,`name`,`age`,`grade`,`status`,`deleted`) VALUES (1,'張三',NULL,NULL,NULL,0);
代碼生成:運行代碼生成器,生成代碼

添加配置:application.properties,如果以下配置已經存在,請忽略此步驟
#那個欄位是邏輯洗掉欄位,也可以在欄位上添加注解@TableLogic,在這里邊配置是全域生效
mybatis-plus.global-config.db-config.logic-delete-field=deleted
#洗掉后欄位的值為1
mybatis-plus.global-config.db-config.logic-delete-value=1
#未洗掉欄位的值為0
mybatis-plus.global-config.db-config.logic-not-delete-value=0
測驗方法:
@Autowired
private StudentMapper studentMapper;
@Test
void testLogicDelete(){
int result = studentMapper.deleteById(1);
System.out.println(result);
}
控制臺截圖:

資料庫截圖:你會發現資料還存在,只是將其中的邏輯洗掉標志由0改為了1,代表邏輯洗掉

8.3、通用列舉
實作自定義列舉有兩種方式,一種是使用注解而另一種是使用實作介面IEnum的方式,在接下來的案例中,我們會分別使用這兩種進行講解,這樣可以讓大家學的更全面一些,
8.3.1、保存列舉值
添加配置:application.properties,如果有以下配置,請忽略此步驟
mybatis-plus.type-enums-package=com.caochenlei.mpdemo.myenum
mybatis-plus.configuration.default-enum-type-handler=org.apache.ibatis.type.EnumOrdinalTypeHandler
創建列舉類:com.caochenlei.mpdemo.myenum.AgeEnum
public enum AgeEnum implements IEnum<Integer> {
ONE(1, "一歲"),
TWO(2, "二歲"),
THREE(3, "三歲");
private int value;
private String desc;
AgeEnum(int value, String desc) {
this.value = value;
this.desc = desc;
}
@Override
public Integer getValue() {
//數值作為列舉值保存到資料庫
return this.value;
}
}
修改物體類:com.caochenlei.mpdemo.pojo.Student
/**
* 學生年齡
*/
private AgeEnum age;
測驗方法:
@Test
void testAgeEnum() {
Student student = new Student();
student.setName("李四");
student.setAge(AgeEnum.THREE);
int result = studentMapper.insert(student);
System.out.println(result);
}
控制臺截圖:

資料庫截圖:

8.3.2、保存列舉名稱
添加配置:application.properties,如果有以下配置,請忽略此步驟
mybatis-plus.type-enums-package=com.caochenlei.mpdemo.myenum
mybatis-plus.configuration.default-enum-type-handler=org.apache.ibatis.type.EnumOrdinalTypeHandler
創建列舉類:com.caochenlei.mpdemo.myenum.GradeEnum
public enum GradeEnum {
PRIMARY(1, "小學"),
SECONDORY(2, "中學"),
HIGH(3, "高中");
private int code;
@EnumValue//描述作為列舉值保存到資料庫
private String desc;
GradeEnum(int code, String desc) {
this.code = code;
this.desc = desc;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
修改物體類:com.caochenlei.mpdemo.pojo.Student
/**
* 學生年紀
*/
private GradeEnum grade;
測驗方法:
@Test
void testGradeEnum() {
Student student = new Student();
student.setName("王五");
student.setGrade(GradeEnum.HIGH);
int result = studentMapper.insert(student);
System.out.println(result);
}
控制臺截圖:

資料庫截圖:

8.4、自動填充功能
我們現在有一個需求,每當插入一個學生的時候,自動的給學生狀態設定為”插入“,每當修改的時候,如果狀態標志位為null,就把標志欄位設定為”修改“,這時候就需要自動填充功能了,
metaobject:元物件,是 Mybatis 提供的一個用于更加方便,更加優雅的訪問物件的屬性,給物件的屬性設定值的一個物件,還會用于包裝物件,支持對 Object 、Map、Collection等物件進行包裝,本質上 metaObject 獲取物件的屬性值或者是給物件的屬性設定值,最終是要通過 Reflector 獲取到屬性的對應方法的 Invoker,最終 invoke,
添加注解:
/**
* 學生狀態
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private String status;
創建包:com.caochenlei.mpdemo.metaObjectHandler
創建自動填充功能處理器:com.caochenlei.mpdemo.metaObjectHandler.MyMetaObjectHandler
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
System.out.println("start insert fill ....");
this.strictInsertFill(metaObject, "status",String.class,"插入");
}
@Override
public void updateFill(MetaObject metaObject) {
System.out.println("start update fill ....");
this.strictUpdateFill(metaObject, "status",String.class,"更新");
}
}
注冊自動填充功能處理器:MybatisPlusConfig
@Bean
public MyMetaObjectHandler myMetaObjectHandler(){
return new MyMetaObjectHandler();
}
測驗方法:依次執行兩個方法
@Test
void testInsertFill(){
Student student = new Student();
student.setName("小六");
int result = studentMapper.insert(student);
System.out.println(result);
}
@Test
void testUpdateFill(){
Student student = studentMapper.selectById(4);
student.setName("李四-修改");
student.setStatus(null);
int result = studentMapper.updateById(student);
System.out.println(result);
}
控制臺截圖:
testInsertFill之后

testUpdateFill之后

資料庫截圖:
testInsertFill之后

testUpdateFill之后

8.5、欄位型別處理器
欄位型別處理器,用于 JavaType 與 JdbcType 之間的轉換,用于 PreparedStatement 設定引數值和從 ResultSet 或 CallableStatement 中取出一個值,本文講解 mybaits-plus 內置常用型別處理器如何通過TableField注解快速注入到 mybatis 容器中,
@Data
@Accessors(chain = true)
@TableName(autoResultMap = true)
public class User {
private Long id;
...
/**
* 注意!! 必須開啟映射注解
*
* @TableName(autoResultMap = true)
*
* 以下兩種型別處理器,二選一,也可以同時存在
*
* 注意!! 選擇對應的 JSON 處理器也必須存在對應 JSON 決議依賴包
*/
@TableField(typeHandler = JacksonTypeHandler.class)
// @TableField(typeHandler = FastjsonTypeHandler.class)
private OtherInfo otherInfo;
}
8.6、自定義ID生成器
匯入資料:
## 洗掉表
DROP TABLE IF EXISTS `tbl_product`;
## 新建表
CREATE TABLE `tbl_product` (
`pid` int(11) NOT NULL COMMENT '商品主鍵',
`pname` varchar(255) DEFAULT NULL COMMENT '商品名稱',
PRIMARY KEY (`pid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='商品';
生成代碼:運行CodeGenerator

溫馨提示:自3.3.0開始,默認使用雪花演算法+UUID(不含中劃線)
重寫方法:
| 方法 | 主鍵生成策略 | 主鍵型別 | 說明 |
|---|---|---|---|
| nextId | ASSIGN_ID | Long,Integer,String | 支持自動轉換為String型別,但數值型別不支持自動轉換,需精準匹配,例如回傳Long,物體主鍵就不支持定義為Integer |
| nextUUID | ASSIGN_UUID,UUID | String | 默認不含中劃線的UUID生成 |
創建包:com.caochenlei.mpdemo.incrementer
創建類:com.caochenlei.mpdemo.incrementer.CustomIdGenerator
public class CustomIdGenerator implements IdentifierGenerator {
private final AtomicLong al = new AtomicLong(1);
@Override
public Long nextId(Object entity) {
//可以將當前傳入的class全類名來作為bizKey或者提取引數來生成bizKey進行分布式Id呼叫生成
String bizKey = entity.getClass().getName();
System.out.println("bizKey:" + bizKey);
MetaObject metaObject = SystemMetaObject.forObject(entity);
String name = (String) metaObject.getValue("pname");
final long id = al.getAndAdd(1);
System.out.println("為" + name + "生成主鍵值->:" + id);
return id;
}
}
注冊類:MybatisPlusConfig
@Bean
public IdentifierGenerator customIdGenerator(){
return new CustomIdGenerator();
}
修改主鍵策略
/**
* 商品主鍵
*/
@TableId(value = "pid", type = IdType.ASSIGN_ID)
private Long pid;
測驗方法:
@Autowired
private ProductMapper productMapper;
@Test
void testCustomIdGenerator() {
Product product = new Product();
product.setPname("手機");
int result = productMapper.insert(product);
System.out.println(result);
}
控制臺截圖:

資料庫截圖:

8.7、Sequence主鍵
在實際開發中,我們經常會使用到MySQL和Oracle資料庫,但是這兩種資料庫對于主鍵有不同的策略,如下:
- MySQL:支持主鍵自增,type = IdType.Auto
- Oracle:支持序列自增,type = IdType.INPUT
那我們Oracle又要如何使用主鍵策略,在這里,我們就不進行一步一步介紹了,我們只提出解決方法
-
在物體類物件上添加注解@KeySequence(value=”序列名”, clazz=主鍵屬性型別.class)
-
在物體類物件的主鍵欄位上添加注解@TableId(value = “主鍵名稱”, type = IdType.INPUT)
@KeySequence(value = "SEQ_ORACLE_INTEGER_KEY", clazz = Integer.class) public class YourEntity { @TableId(value = "ID", type = IdType.INPUT) private Integer id; } -
在全域配置中注冊com.baomidou.mybatisplus.incrementer.OracleKeyGenerator
@Bean public IKeyGenerator keyGenerator() { return new oracleKeyGenerator(); }
除了Oracle,MyBatis-Plus還內置支持以下資料庫序列:
- DB2KeyGenerator
- H2KeyGenerator
- KingbaseKeyGenerator
- OracleKeyGenerator
- PostgreKeyGenerator
如果內置支持不滿足你的需求,可實作IKeyGenerator介面來進行擴展,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/221070.html
標籤:其他
上一篇:AttributeError: 'NoneType' object has no attribute 'eval'
下一篇:DS--最長重復子串
