日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Mybatis-Plus 详解

發布時間:2024/5/14 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Mybatis-Plus 详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. Mybatis-Plus概念

1.1 Mybatis-Plus介紹

官?: https://mybatis.plus/ https://mp.baomidou.com/ Mybatis-Plus 介紹 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 查詢
  • 分?插件?持多種數據庫:?持 MySQLMariaDBOracleDB2H2HSQLSQLitePostgreSQLServer 等多種數據庫
  • 內置性能分析插件:可輸出 Sql 語句以及其執?時間,建議開發測試時啟?該功能,能快速揪出慢查詢
  • 內置全局攔截插件:提供全表 delete update 操作智能分析阻斷,也可?定義攔截規則,預防誤操作

1.3 架構

1.4 作者

Mybatis-Plus 是由 baomidou (苞??)組織開發并且開源的,?前該組織?概有 30 ?左右。 碼云地址: https://gitee.com/organizations/baomidou

2. Mybatis-Plus快速??

2.1 安裝

全新的 MyBatis-Plus 3.0 版本基于 JDK8 ,提供了 lambda 形式的調?,所以安裝集成 MP3.0 要求 如下:
  • JDK 8+
  • Maven or Gradle
Release Spring Boot Maven <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.0</version> </dependency> Spring MVC Maven: <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus</artifactId><version>3.4.0</version> </dependency> 對于 Mybatis 整合 MP 有常常有三種?法,分別是 Mybatis+MP Spring+Mybatis+MP Spring Boot+Mybatis+MP

2.2 創建數據庫以及表

創建 User 表,其表結構如下:

-- 創建測試表 DROP TABLE IF EXISTS tb_user; CREATE TABLE user (id BIGINT(20) NOT NULL COMMENT '主鍵ID',name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',age INT(11) NULL DEFAULT NULL COMMENT '年齡',email VARCHAR(50) NULL DEFAULT NULL COMMENT '郵箱',PRIMARY KEY (id) ); -- 插?測試數據 INSERT INTO user (id, name, age, email) VALUES (1, 'Jone', 18, 'test1@baomidou.com'), (2, 'Jack', 20, 'test2@baomidou.com'), (3, 'Tom', 28, 'test3@baomidou.com'), (4, 'Sandy', 21, 'test4@baomidou.com'), (5, 'Billie', 24, 'test5@baomidou.com');

2.3 創建?程

?導?依賴:

<dependencies><!-- mybatis-plus插件依賴 --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus</artifactId><version>3.1.1</version></dependency><!--Mysql--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version></dependency><!--連接池--><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.0.11</version></dependency><!--簡化bean代碼的?具包--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.4</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>1.6.4</version></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>1.8</source><target>1.8</target></configuration></plugin></plugins></build>

2.4 Mybatis + MP

下?演示,通過純 Mybatis Mybatis-Plus 整合。 創建? Module <?xml version="1.0" encoding="UTF-8" ?> <project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>lagou-mybatis-plus</artifactId><groupId>com.lagou.mp</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>lagou-mybatis-plus-simple</artifactId> </project> log4j.properties log4j.rootLogger=DEBUG,A1 log4j.appender.A1=org.apache.log4j.ConsoleAppender log4j.appender.A1.layout=org.apache.log4j.PatternLayout log4j.appender.A1.layout.ConversionPattern=[%t] [%c]-[%p] %m%n Mybatis 實現查詢 User 第?步,編寫 mybatis-config.xml ?件 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration><properties resource="jdbc.properties"></properties><!--environments: 運?環境--><environments default="development"><environment id="development"><!--當前的事務事務管理器是JDBC--><transactionManager type="JDBC"></transactionManager><!--數據源信息 POOLED:使?mybatis的連接池--><dataSource type="POOLED"><property name="driver" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></dataSource></environment></environments><!--引?映射配置?件--><mappers><mapper resource="mapper/UserMapper.xml"></mapper></mappers> </configuration> 第?步,編寫 User 實體對象:(這?使? lombok 進?了進化 bean 操作) @Data // getter setter @toString @NoArgsConstructor @AllArgsConstructor public class User {private Long id;private String name;private Integer age;private String email; } 第三步,編寫 UserMapper 接?: public interface UserMapper {List<User> findAll(); } 第四步,編寫 UserMapper.xml ?件: <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.lagou.mapper.UserMapper"><!-- 查詢所有 --><select id="findAll" resultType="com.lagou.pojo.User">select * from user</select> </mapper> 第五步,編寫 TestMybatis 測試?例: public class MPTest {@Testpublic void test1() throws IOException {InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);SqlSession sqlSession = sqlSessionFactory.openSession();UserMapper mapper = sqlSession.getMapper(UserMapper.class);List<User> all = mapper.findAll();for (User user : all) {System.out.println(user);}} } 測試結果: User(id=1, name=Jone, age=18, email=test1@baomidou.com) User(id=2, name=Jack, age=20, email=test2@baomidou.com) User(id=3, name=Tom, age=28, email=test3@baomidou.com) User(id=4, name=Sandy, age=21, email=test4@baomidou.com) User(id=5, name=Billie, age=24, email=test5@baomidou.com) 注:如果實體類名稱和表名稱不?致,可以在實體類上添加注解 @TableName(" 指定數據庫表名 ") Mybatis+MP 實現查詢 User 第?步,將 UserMapper 繼承 BaseMapper ,將擁有了 BaseMapper 中的所有?法: import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.lagou.pojo.User; public interface UserMapper extends BaseMapper<User> { } 第?步,使? MP 中的 MybatisSqlSessionFactoryBuilder 進程構建: @Test public void test2() throws IOException {InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");//這?使?的是MP中的MybatisSqlSessionFactoryBuilderSqlSessionFactory sqlSessionFactory = new MybatisSqlSessionFactoryBuilder().build(resourceAsStream);SqlSession sqlSession = sqlSessionFactory.openSession();UserMapper mapper = sqlSession.getMapper(UserMapper.class);// 可以調?BaseMapper中定義的?法List<User> all = mapper.selectList(null);for (User user : all) {System.out.println(user);} } 測試: User(id=1, name=Jone, age=18, email=test1@baomidou.com) User(id=2, name=Jack, age=20, email=test2@baomidou.com) User(id=3, name=Tom, age=28, email=test3@baomidou.com) User(id=4, name=Sandy, age=21, email=test4@baomidou.com) User(id=5, name=Billie, age=24, email=test5@baomidou.com) 注:如果實體類名稱和表名稱不?致,可以在實體類上添加注解 @TableName(" 指定數據庫表名 ") 簡單說明:
  • 由于使?了 MybatisSqlSessionFactoryBuilder進?了構建,繼承的BaseMapper中的?法就載?到了SqlSession中,所以就可以直接使?相關的?法;
  • 如圖

2.5 Spring + Mybatis + MP

引?了 Spring 框架,數據源、構建等?作就交給了 Spring 管理。 創建? Module <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>lagou-mybatis-plus</artifactId><groupId>com.lagou.mp</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>lagou-mybatis-plus-spring</artifactId><properties><spring.version>5.1.6.RELEASE</spring.version></properties><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>${spring.version}</version></dependency></dependencies> 實現查詢 User 第?步,編寫 jdbc.properties jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://127.0.0.1:3306/mp?serverTimezone=GMT%2B8&useSSL=false jdbc.username=root jdbc.password=root 第?步,編寫 applicationContext.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!--引?properties--><context:property-placeholder location="classpath:jdbc.properties"/><!--dataSource--><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></bean><!--這?使?MP提供的sqlSessionFactory,完成spring與mp的整合--><bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean" ><property name="dataSource" ref="dataSource"/></bean><!--掃描mapper接?,使?的依然是mybatis原?的掃描器--><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.lagou.mapper"/></bean> </beans> 第三步,編寫 User 對象以及 UserMapper 接?: @Data @NoArgsConstructor @AllArgsConstructor public class User {private Long id;private String name;private Integer age;private String email; } public interface UserMapper extends BaseMapper<User> {List<User> findAll(); } 第四步,編寫測試?例: @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:applicationContext.xml") public class TestSpringMP {@Autowiredprivate UserMapper userMapper;@Testpublic void test2() throws IOException {List<User> users = this.userMapper.selectList(null);for (User user : users) {System.out.println(user);}}

2.6 SpringBoot + Mybatis + MP

使? SpringBoot 將進?步的簡化 MP 的整合,需要注意的是,由于使? SpringBoot 需要繼承 parent ,所以需要重新創建?程,并不是創建?Module 創建?程

導?依賴 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--簡化代碼的?具包--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!--mybatis-plus的springboot?持--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.1.1</version></dependency><!--mysql驅動--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build> log4j.properties log4j.rootLogger=DEBUG,A1 log4j.appender.A1=org.apache.log4j.ConsoleAppender log4j.appender.A1.layout=org.apache.log4j.PatternLayout log4j.appender.A1.layout.ConversionPattern=[%t] [%c]-[%p] %m%n

編寫application.properties

spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mp? useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=tr ue&useSSL=false spring.datasource.username=root spring.datasource.password=root

編寫pojo

@Data @NoArgsConstructor @AllArgsConstructor public class User {private Long id;private String name;private Integer age;private String email; } 編寫 mapper public interface UserMapper extends BaseMapper<User> { } 編寫啟動類 package com.lagou.mp; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.WebApplicationType; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; @MapperScan("com.lagou.mp.mapper") //設置mapper接?的掃描包 @SpringBootApplication public class MyApplication {public static void main(String[] args) {SpringApplication.run(MyApplication.class, args);} }

編寫測試?例

package com.lagou.mp; import com.lagou.mp.mapper.UserMapper; import com.lagou.mp.pojo.User; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.List; @RunWith(SpringRunner.class) @SpringBootTest public class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testpublic void testSelect() {List<User> userList = userMapper.selectList(null);for (User user : userList) {System.out.println(user);}} } 測試: User(id=1, name=Jone, age=18, email=test1@baomidou.com) User(id=2, name=Jack, age=20, email=test2@baomidou.com) User(id=3, name=Tom, age=28, email=test3@baomidou.com) User(id=4, name=Sandy, age=21, email=test4@baomidou.com) User(id=5, name=Billie, age=24, email=test5@baomidou.com)

3. 通?CRUD

通過前?的學習,我們了解到通過繼承 BaseMapper 就可以獲取到各種各樣的單表操作,接下來我們將詳細講解這些操作。

3.1 插?操作

?法定義 /*** 插??條記錄** @param entity 實體對象.*/int insert(T entity); 測試?例 @RunWith(SpringRunner.class) @SpringBootTest public class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testpublic void testInsert(){User user = new User();user.setAge(18);user.setEmail("test@lagou.cn");user.setName("?慕");//返回的result是受影響的?數,并不是?增后的idint result = userMapper.insert(user);System.out.println(result);System.out.println(user.getId());} } 測試 1 1318744682116739074 可以看到,數據已經寫?到了數據庫,但是, id 的值不正確,我們期望的是數據庫?增?,實際是 MP ? 成了 id 的值寫?到了數據庫。 如何設置 id 的?成策略呢? MP ?持的 id 策略: package com.baomidou.mybatisplus.annotation; import lombok.Getter; /** * ?成ID類型枚舉類 * * @author hubin * @since 2015-11-10 */ @Getter public enum IdType {/*** 數據庫ID?增*/AUTO(0),/*** 該類型為未設置主鍵類型*/NONE(1),/*** ?戶輸?ID* <p>該類型可以通過??注冊?動填充插件進?填充</p>*/INPUT(2),/* 以下3種類型、只有當插?對象ID 為空,才?動填充。 *//*** 全局唯?ID (idWorker)*/ID_WORKER(3),/*** 全局唯?ID (UUID)*/UUID(4),/*** 字符串全局唯?ID (idWorker 的字符串表示)*/ID_WORKER_STR(5);private final int key;IdType(int key) {this.key = key;} }

修改 User 對象: package com.lagou.mp.pojo; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor @AllArgsConstructor @TableName("tb_user") public class User {@TableId(type = IdType.AUTO) //指定id類型為?增?private Long id;private String userName;private String password;private String name;private Integer age;private String email; } 數據插?成功:

@TableField MP 中通過 @TableField 注解可以指定字段的?些屬性,常常解決的問題有 2 個: 1 、對象中的屬性名和字段名不?致的問題(?駝峰) 2 、對象中的屬性字段在表中不存在的問題 使?:

?其他?法,如?字段不加?查詢字段:

?效果:

3.2 更新操作

MP 中,更新操作有 2 種,?種是根據 id 更新,另?種是根據條件更新。 根據 id 更新 ?法定義: /*** 根據 ID 修改** @param entity 實體對象*/int updateById(@Param(Constants.ENTITY) T entity); 測試: @RunWith(SpringRunner.class) @SpringBootTest public class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testpublic void testUpdateById() {User user = new User();user.setId(6L); //主鍵user.setAge(21); //更新的字段//根據id更新,更新不為null的字段this.userMapper.updateById(user);} } 結果:

根據條件更新 ?法定義: /*** 根據 whereEntity 條件,更新記錄** @param entity 實體對象 (set 條件值,可以為 null)* @param updateWrapper 實體對象封裝操作類(可以為 null,??的 entity ?于?成 where 語句)*/int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper); 測試?例: package com.lagou.mp; import com.lagou.mp.mapper.UserMapper; import com.lagou.mp.pojo.User; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import net.minidev.json.writer.UpdaterMapper; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.List; @RunWith(SpringRunner.class) @SpringBootTest public class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testpublic void testUpdate() {User user = new User();user.setAge(22); //更新的字段//更新的條件QueryWrapper<User> wrapper = new QueryWrapper<>();wrapper.eq("id", 6);//執?更新操作int result = this.userMapper.update(user, wrapper);System.out.println("result = " + result);} } 或者,通過 UpdateWrapper 進?更新: @Testpublic void testUpdate() {//更新的條件以及字段UpdateWrapper<User> wrapper = new UpdateWrapper<>();wrapper.eq("id", 6).set("age", 23);//執?更新操作int result = this.userMapper.update(null, wrapper);System.out.println("result = " + result);} 測試結果: [main] [com.lagou.mp.mapper.UserMapper.update]-[DEBUG] == > Preparing: UPDATE tb_user SET age = ? WHERE id = ? [main] [com.lagou.mp.mapper.UserMapper.update]-[DEBUG] == > Parameters: 23 (Integer), 6 (Integer) [main] [com.lagou.mp.mapper.UserMapper.update]-[DEBUG] < == Updates: 1 均可達到更新的效果。 關于 wrapper 更多的?法后?會詳細講解。

3.3 刪除操作

deleteById ?法定義: /** * 根據 ID 刪除 * * @param id 主鍵ID */ int deleteById(Serializable id); 測試?例: package com.lagou.mp; import com.lagou.mp.mapper.UserMapper; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest public class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testpublic void testDeleteById() {//執?刪除操作int result = this.userMapper.deleteById(6L);System.out.println("result = " + result);} }

結果:

[main] [com.lagou.mp.mapper.UserMapper.deleteById]-[DEBUG] == > Preparing: DELETE FROM tb_user WHERE id = ? [main] [com.lagou.mp.mapper.UserMapper.deleteById]-[DEBUG] == > Parameters: 6 (Long) [main] [com.lagou.mp.mapper.UserMapper.deleteById]-[DEBUG] < == Updates: 1 數據被刪除。 deleteByMap ?法定義: /*** 根據 columnMap 條件,刪除記錄** @param columnMap 表字段 map 對象*/int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap); 測試?例: package com.lagou.mp; import com.lagou.mp.mapper.UserMapper; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.HashMap; import java.util.Map; @RunWith(SpringRunner.class) @SpringBootTest public class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testpublic void testDeleteByMap() {Map<String, Object> columnMap = new HashMap<>();columnMap.put("age",21);columnMap.put("name","?慕");//將columnMap中的元素設置為刪除的條件,多個之間為and關系int result = this.userMapper.deleteByMap(columnMap);System.out.println("result = " + result);} }

結果:

[main] [com.lagou.mp.mapper.UserMapper.deleteByMap]-[DEBUG] == > Preparing: DELETE FROM tb_user WHERE name = ? AND age = ? [main] [com.lagou.mp.mapper.UserMapper.deleteByMap]-[DEBUG] == > Parameters: ? (String), 21 (Integer) [main] [com.lagou.mp.mapper.UserMapper.deleteByMap]-[DEBUG] < == Updates: 0 delete ?法定義: /** * 根據 entity 條件,刪除記錄 * * @param wrapper 實體對象封裝操作類(可以為 null) */ int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper); 測試?例: package com.lagou.mp; import com.lagou.mp.mapper.UserMapper; import com.lagou.mp.pojo.User; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.junit.Test; 結果: 3.3.4、deleteBatchIds ?法定義: import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.HashMap; import java.util.Map; @RunWith(SpringRunner.class) @SpringBootTest public class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testpublic void testDeleteByMap() {User user = new User();user.setAge(20);user.setName("?慕");//將實體對象進?包裝,包裝為操作條件QueryWrapper<User> wrapper = new QueryWrapper<>(user);int result = this.userMapper.delete(wrapper);System.out.println("result = " + result);} }

結果:

[main] [com.lagou.mp.mapper.UserMapper.delete]-[DEBUG] == > Preparing: DELETE FROM tb_user WHERE name = ? AND age = ? [main] [com.lagou.mp.mapper.UserMapper.delete]-[DEBUG] == > Parameters: ?慕 (String), 20 (Integer) [main] [com.lagou.mp.mapper.UserMapper.delete]-[DEBUG] < == Updates: 0

3.3.4deleteBatchIds

?法定義: /*** 刪除(根據ID 批量刪除)** @param idList 主鍵ID列表(不能為 null 以及 empty)*/int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList); 測試?例: package com.lagou.mp; import com.lagou.mp.mapper.UserMapper; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.Arrays; @RunWith(SpringRunner.class) @SpringBootTest public class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testpublic void testDeleteByMap() {//根據id集合批量刪除int result = this.userMapper.deleteBatchIds(Arrays.asList(1L,10L,20L));System.out.println("result = " + result);} } 結果: [main] [com.lagou.mp.mapper.UserMapper.deleteBatchIds]-[DEBUG] == > Preparing: DELETE FROM tb_user WHERE id IN ( ? , ? , ? ) [main] [com.lagou.mp.mapper.UserMapper.deleteBatchIds]-[DEBUG] == > Parameters: 1 (Long), 10 (Long), 20 (Long) [main] [com.lagou.mp.mapper.UserMapper.deleteBatchIds]-[DEBUG] < == Updates: 1

3.4 查詢操作

MP 提供了多種查詢操作,包括根據 id 查詢、批量查詢、查詢單條數據、查詢列表、分?查詢等操作。

3.4.1selectById

?法定義: /*** 根據 ID 查詢** @param id 主鍵ID*/T selectById(Serializable id); 測試?例: package com.lagou.mp; import com.lagou.mp.mapper.UserMapper; import com.lagou.mp.pojo.User; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest public class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testpublic void testSelectById() {//根據id查詢數據User user = this.userMapper.selectById(2L);System.out.println("result = " + user);} } 結果: result = User (id = 2 , name = Jack, age = 20 , email = test2@baomidou.com)

3.4.2selectBatchIds

?法定義: /** * 查詢(根據ID 批量查詢) * * @param idList 主鍵ID列表(不能為 null 以及 empty) */ List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList); 測試?例: package com.lagou.mp; import com.lagou.mp.mapper.UserMapper; import com.lagou.mp.pojo.User; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.Arrays; import java.util.List; @RunWith(SpringRunner.class) @SpringBootTest public class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testpublic void testSelectBatchIds() {//根據id集合批量查詢List<User> users = this.userMapper.selectBatchIds(Arrays.asList(2L, 3L, 10L));for (User user : users) {System.out.println(user);}} } 結果: User (id = 2 , name = Jack, age = 20 , email = test2@baomidou.com) User (id = 3 , name = Tom, age = 28 , email = test3@baomidou.com)

3.4.3selectOne

?法定義: /** * 根據 entity 條件,查詢?條記錄 * * @param queryWrapper 實體對象封裝操作類(可以為 null) */ T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); 測試?例: package com.lagou.mp; import com.lagou.mp.mapper.UserMapper; import com.lagou.mp.pojo.User; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest public class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testpublic void testSelectOne() {QueryWrapper<User> wrapper = new QueryWrapper<User>();wrapper.eq("name", "jack");//根據條件查詢?條數據,如果結果超過?條會報錯User user = this.userMapper.selectOne(wrapper);System.out.println(user);} } 結果: User (id = 2 , name = Jack, age = 20 , email = test2@baomidou.com)

3.4.4selectCount

?法定義: /** * 根據 Wrapper 條件,查詢總記錄數 * * @param queryWrapper 實體對象封裝操作類(可以為 null) */ Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); 測試?例: package com.lagou.mp; import com.lagou.mp.mapper.UserMapper; import com.lagou.mp.pojo.User; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest public class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testpublic void testSelectCount() {QueryWrapper<User> wrapper = new QueryWrapper<User>();wrapper.gt("age", 23); //年齡?于23歲//根據條件查詢數據條數Integer count = this.userMapper.selectCount(wrapper);System.out.println("count = " + count);} } 結果: count = 2

3.4.5selectList

?法定義: /** * 根據 entity 條件,查詢全部記錄 * * @param queryWrapper 實體對象封裝操作類(可以為 null) */ List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); 測試?例: package com.lagou.mp; import com.lagou.mp.mapper.UserMapper; import com.lagou.mp.pojo.User; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.List; @RunWith(SpringRunner.class) @SpringBootTest public class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testpublic void testSelectList() {QueryWrapper<User> wrapper = new QueryWrapper<User>();wrapper.gt("age", 23); //年齡?于23歲//根據條件查詢數據List<User> users = this.userMapper.selectList(wrapper);for (User user : users) {System.out.println("user = " + user);}} } 結果: user = User (id = 3 , name = Tom, age = 28 , email = test3@baomidou.com) user = User (id = 5 , name = Billie, age = 24 , email = test5@baomidou.com)

3.4.6selectPage

?法定義: /** * 根據 entity 條件,查詢全部記錄(并翻?) * * @param page 分?查詢條件(可以為 RowBounds.DEFAULT) * @param queryWrapper 實體對象封裝操作類(可以為 null) */ IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper); 配置分?插件: package com.lagou.mp; import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; import org.mybatis.spring.annotation.MapperScan; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration @MapperScan("com.lagou.mp.mapper") //設置mapper接?的掃描包 public class MybatisPlusConfig {/*** 分?插件*/@Beanpublic PaginationInterceptor paginationInterceptor() {return new PaginationInterceptor();} } 測試?例: package com.lagou.mp; import com.lagou.mp.mapper.UserMapper; import com.lagou.mp.pojo.User; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.List; @RunWith(SpringRunner.class) @SpringBootTest public class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testpublic void testSelectPage() {QueryWrapper<User> wrapper = new QueryWrapper<User>();wrapper.gt("age", 20); //年齡?于20歲Page<User> page = new Page<>(1,1);//根據條件查詢數據IPage<User> iPage = this.userMapper.selectPage(page, wrapper);System.out.println("數據總條數:" + iPage.getTotal());System.out.println("總?數:" + iPage.getPages());List<User> users = iPage.getRecords();for (User user : users) {System.out.println("user = " + user);}} }

結果:

數據總條數: 4 總?數: 4 user = User (id = 3 , name = Tom, age = 28 , email = test3@baomidou.com)

3.5 SQL注?的原理

前?我們已經知道, MP 在啟動后會將 BaseMapper 中的?系列的?法注冊到 meppedStatements 中, 那么究竟是如何注?的呢?流程?是怎么樣的?下?我們將?起來分析下。 MP 中, ISqlInjector 負責 SQL 的注??作,它是?個接?, AbstractSqlInjector 是它的實現類,實現關系如下:

AbstractSqlInjector 中,主要是由 inspectInject() ?法進?注?的,如下: @Override public void inspectInject(MapperBuilderAssistant builderAssistant, Class<?> mapperClass) {Class<?> modelClass = extractModelClass(mapperClass);if (modelClass != null) {String className = mapperClass.toString();Set<String> mapperRegistryCache = GlobalConfigUtils.getMapperRegistryCache(builderAssistant.getConfiguration());if (!mapperRegistryCache.contains(className)) {List<AbstractMethod> methodList = this.getMethodList();if (CollectionUtils.isNotEmpty(methodList)) {TableInfo tableInfo = TableInfoHelper.initTableInfo(builderAssistant, modelClass);// 循環注??定義?法methodList.forEach(m -> m.inject(builderAssistant, mapperClass, modelClass, tableInfo));} else {logger.debug(mapperClass.toString() + ", No effective injection method was found.");}mapperRegistryCache.add(className);}} } 在實現?法中, methodList.forEach(m -> m.inject(builderAssistant, mapperClass, modelClass, tableInfo)); 是關鍵,循環遍歷?法,進?注?。 最終調?抽象?法 injectMappedStatement 進?真正的注?: /*** 注??定義 MappedStatement** @param mapperClass mapper 接?* @param modelClass mapper 泛型* @param tableInfo 數據庫表反射信息* @return MappedStatement*/public abstract MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo); 查看該?法的實現:

SelectById 為例查看: public class SelectById extends AbstractMethod {@Overridepublic MappedStatement injectMappedStatement(Class<?> mapperClass, Class<? > modelClass, TableInfo tableInfo) {SqlMethod sqlMethod = SqlMethod.LOGIC_SELECT_BY_ID;SqlSource sqlSource = new RawSqlSource(configuration, String.format(sqlMethod.getSql(),sqlSelectColumns(tableInfo, false),tableInfo.getTableName(), tableInfo.getKeyColumn(), tableInfo.getKeyProperty(),tableInfo.getLogicDeleteSql(true, false)), Object.class);return this.addSelectMappedStatement(mapperClass, sqlMethod.getMethod(), sqlSource, modelClass, tableInfo);} } 可以看到,?成了 SqlSource 對象,再將 SQL 通過 addSelectMappedStatement ?法添加到meppedStatements中。

4. 配置

MP 中有?量的配置,其中有?部分是 Mybatis 原?的配置,另?部分是 MP 的配置,詳情: https://m ybatis.plus/config/ 下?我們對常?的配置做講解。

4.1、基本配置

4.1.1configLocation

MyBatis 配置?件位置,如果有單獨的 MyBatis 配置,請將其路徑配置到 configLocation 中。 MyBatis Configuration 的具體內容請參考 MyBatis 官??檔 Spring Boot mybatis-plus.config-location = classpath:mybatis-config.xml

Spring MVC

<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean" ><property name="configLocation" value="classpath:mybatis-config.xml"/> </bean>

4.1.2mapperLocations

MyBatis Mapper 所對應的 XML ?件位置,如果您在 Mapper 中有?定義?法( XML 中有?定義實現),需要進?該配置,告訴 Mapper 所對應的 XML ?件位置。 Spring Boot mybatis-plus.mapper-locations = classpath*:mybatis/*.xml Spring MVC <bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean" ><property name="mapperLocations" value="classpath*:mybatis/*.xml"/> </bean> Maven 多模塊項?的掃描路徑需以 classpath*: 開頭 (即加載多個 jar 包下的 XML ?件) 測試: UserMapper.xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.lagou.mp.mapper.UserMapper"><select id="findById" resultType="com.lagou.mp.pojo.User">select * from tb_user where id = #{id}</select> </mapper> package com.lagou.mp.mapper; import com.lagou.mp.pojo.User; import com.baomidou.mybatisplus.core.mapper.BaseMapper; public interface UserMapper extends BaseMapper<User> {User findById(Long id); } 測試?例: package com.lagou.mp; import com.lagou.mp.mapper.UserMapper; import com.lagou.mp.pojo.User; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest public class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testpublic void testSelectPage() {User user = this.userMapper.findById(2L);System.out.println(user);} } 運?結果:

4.1.3typeAliasesPackage ?

MyBaits 別名包掃描路徑,通過該屬性可以給包中的類注冊別名,注冊后在 Mapper 對應的 XML ?件中可以直接使?類名,?不?使?全限定的類名(即 XML 中調?的時候不?包含包名)。 Spring Boot mybatis-plus.type-aliases-package = com.lagou.mp.pojo Spring MVC <bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean" ><property name="typeAliasesPackage" value="com.baomidou.mybatisplus.samples.quickstart.entity"/> </bean>

4.2、進階配置

本部分( Configuration )的配置?都為 MyBatis 原??持的配置,這意味著您可以通過 MyBatis XML配置?件的形式進?配置。

4.2.1mapUnderscoreToCamelCase

  • 類型: boolean
  • 默認值: true
是否開啟?動駝峰命名規則( camel case )映射,即從經典數據庫列名 A_COLUMN (下劃線命名) 到經典 Java 屬性名 aColumn (駝峰命名) 的類似映射。 注意: 此屬性在 MyBatis 中原默認值為 false ,在 MyBatis-Plus 中,此屬性也將?于?成最終的 SQL 的select body 如果您的數據庫命名符合規則?需使? @TableField 注解指定數據庫字段名 示例( SpringBoot ): ? #關閉?動駝峰映射,該參數不能和mybatis-plus.config-location同時存在 mybatis-plus.configuration.map-underscore-to-camel-case=false

4.2.2cacheEnabled

  • 類型: boolean
  • 默認值: true
全局地開啟或關閉配置?件中的所有映射器已經配置的任何緩存,默認為 true 示例: mybatis-plus.configuration.cache-enabled=false

4.3DB 策略配置

4.3.1idType

  • 類型: com.baomidou.mybatisplus.annotation.IdType
  • 默認值: ID_WORKER
全局默認主鍵類型,設置后,即可省略實體對象中的 @TableId(type = IdType.AUTO) 配置。 示例: SpringBoot mybatis-plus.global-config.db-config.id-type=auto SpringMVC <!--這?使?MP提供的sqlSessionFactory,完成了Spring與MP的整合--><bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean" ><property name="dataSource" ref="dataSource"/><property name="globalConfig"><bean class="com.baomidou.mybatisplus.core.config.GlobalConfig"><property name="dbConfig"><bean class="com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig"><property name="idType" value="AUTO"/></bean></property></bean></property></bean>

4.3.2tablePrefix

  • 類型: String
  • 默認值: null
表名前綴,全局配置后可省略 @TableName() 配置。 SpringBoot mybatis-plus.global-config.db-config.table-prefix=tb_ SpringMVC <bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean" ><property name="dataSource" ref="dataSource"/><property name="globalConfig"><bean class="com.baomidou.mybatisplus.core.config.GlobalConfig"><property name="dbConfig"><bean class="com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig"><property name="idType" value="AUTO"/><property name="tablePrefix" value="tb_"/></bean></property></bean></property></bean>

5. 條件構造器

MP 中, Wrapper 接?的實現類關系如下:

可以看到, AbstractWrapper AbstractChainWrapper 是重點實現,接下來我們重點學習 AbstractWrapper 以及其?類。 說明 : QueryWrapper(LambdaQueryWrapper) UpdateWrapper(LambdaUpdateWrapper) 的?類 ?于?成 sql where 條件 , entity 屬性也?于?成 sql where 條件 注意 : entity ?成的 where 條件與 使?各個 api ?成的 where 條件 沒有任何關聯?為 官??檔地址: https://mybatis.plus/guide/wrapper.html

5.1allEq

5.1.1、說明

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 = ' ?王 '

5.1.2、測試?例

package com.lagou.mp; import com.lagou.mp.mapper.UserMapper; import com.lagou.mp.pojo.User; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.HashMap; import java.util.List; import java.util.Map;@RunWith(SpringRunner.class) @SpringBootTest public class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testpublic void testWrapper() {QueryWrapper<User> wrapper = new QueryWrapper<>();//設置條件Map<String,Object> params = new HashMap<>();params.put("name", "jack");params.put("age", "20"); // wrapper.allEq(params);//SELECT * FROM tb_user WHERE password IS NULL AND name = ? AND age = ? // wrapper.allEq(params,false); //SELECT * FROM tb_user WHERE name = ? AND age = ? // wrapper.allEq((k, v) -> (k.equals("name") || k.equals("age")) ,params);//SELECT * FROM tb_user WHERE name = ? AND age = ?List<User> users = this.userMapper.selectList(wrapper);for (User user : users) {System.out.println(user);}} }

5.2、基本?較操作

  • eq
    • 等于 =
  • ne
    • 不等于 <>
  • gt
    • ?于 >
  • ge
    • ?于等于 >=
  • lt
    • ?于 <
  • le
    • ?于等于 <=
  • between
    • BETWEEN 1 AND 2
  • notBetween
    • NOT BETWEEN 1 AND 2
  • in
    • 字段 IN (value.get(0), value.get(1), ...)
  • notIn
    • 字段 NOT IN (v0, v1, ...)
測試?例: package com.lagou.mp; import com.lagou.mp.mapper.UserMapper; import com.lagou.mp.pojo.User; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.List; @RunWith(SpringRunner.class) @SpringBootTest public class UserMapperTest {@Autowiredprivate UserMapper userMapper;QueryWrapper<User> wrapper = new QueryWrapper<>();//SELECT id,name,age,email FROM tb_user WHERE password = ? AND age >= ? AND name IN (?,?,?)wrapper.eq("email", "test2@baomidou.com").ge("age", 20).in("name", "jack", "jone", "tom");List<User> users = this.userMapper.selectList(wrapper);for (User user : users) {System.out.println(user);}} }

5.3、模糊查詢

  • like
    • LIKE '%值%'
    • 例: like("name", "") ---> name like '%%'
  • notLike
    • NOT LIKE '%%'
    • : notLike("name", "") ---> name not like '%%'
  • likeLeft
    • LIKE '%'
    • : likeLeft("name", "") ---> name like '%'
  • likeRight
    • LIKE '%'
    • : likeRight("name", "") ---> name like '%'
測試?例: package com.lagou.mp; import com.lagou.mp.mapper.UserMapper; import com.lagou.mp.pojo.User; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.List; @RunWith(SpringRunner.class) @SpringBootTest public class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testpublic void testWrapper() {QueryWrapper<User> wrapper = new QueryWrapper<>();//SELECT id,user_name,password,name,age,email FROM tb_user WHERE name LIKE ?//Parameters: %?%(String)wrapper.like("name", "?");List<User> users = this.userMapper.selectList(wrapper);for (User user : users) {System.out.println(user);}} }

5.4、排序

  • orderBy
    • 排序:ORDER BY 字段, ...
    • : orderBy(true, true, "id", "name") ---> order by id ASC,name ASC
  • orderByAsc
    • 排序:ORDER BY 字段, ... ASC
    • : orderByAsc("id", "name") ---> order by id ASC,name ASC
  • orderByDesc
    • 排序:ORDER BY 字段, ... DESC
    • : orderByDesc("id", "name") ---> order by id DESC,name DESC
測試?例: package com.lagou.mp; import com.lagou.mp.mapper.UserMapper; import com.lagou.mp.pojo.User; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.List; @RunWith(SpringRunner.class) @SpringBootTest public class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testpublic void testWrapper() {QueryWrapper<User> wrapper = new QueryWrapper<>();//SELECT id,user_name,password,name,age,email FROM tb_user ORDER BY age DESCwrapper.orderByDesc("age");List<User> users = this.userMapper.selectList(wrapper);for (User user : users) {System.out.println(user);}} }

5.5、邏輯查詢

  • or
    • 拼接 OR
    • 主動調? or 表示緊接著下?個?法不是? and 連接!(不調? or 則默認為使? and 連接)
  • and
    • AND 嵌套
    • : and(i -> i.eq("name", "李?").ne("status", "活著")) ---> and (name = '?' and status <> '活著')
測試?例: package com.lagou.mp; import com.lagou.mp.mapper.UserMapper; import com.lagou.mp.pojo.User; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.List; @RunWith(SpringRunner.class) @SpringBootTest public class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testpublic void testWrapper() {QueryWrapper<User> wrapper = new QueryWrapper<>();//SELECT id,user_name,password,name,age,email FROM tb_user WHERE name= ? OR age = ?wrapper.eq("name","jack").or().eq("age", 24);List<User> users = this.userMapper.selectList(wrapper);for (User user : users) {System.out.println(user);}} }

5.6select

MP 查詢中,默認查詢所有的字段,如果有需要也可以通過 select ?法進?指定字段。 package com.lagou.mp; import com.lagou.mp.mapper.UserMapper; import com.lagou.mp.pojo.User; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.List; @RunWith(SpringRunner.class) @SpringBootTest public class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testpublic void testWrapper() {QueryWrapper<User> wrapper = new QueryWrapper<>();//SELECT id,name,age FROM tb_user WHERE name = ? OR age = ?wrapper.eq("name", "jack").or().eq("age", 24).select("id", "name", "age");List<User> users = this.userMapper.selectList(wrapper);for (User user : users) {System.out.println(user);}} }

6. ActiveRecord

ActiveRecord (簡稱 AR )?直?受動態語?( PHP Ruby 等)的喜愛,? Java 作為準靜態語?,對于 ActiveRecord 往往只能感嘆其優雅,所以我們也在 AR 道路上進?了?定的探索,希望?家能夠喜歡。? 什么是 ActiveRecord ActiveRecord 也屬于 ORM (對象關系映射)層,由 Rails 最早提出,遵循標準的 ORM 模型:表映射到記錄,記錄映射到對象,字段映射到對象屬性。配合遵循的命名和配置慣例,能夠很?程度的快速實現模型的操作,?且簡潔易懂。 ActiveRecord 的主要思想是:
  • 每?個數據庫表對應創建?個類,類的每?個對象實例對應于數據庫中表的??記錄;通常 表的每個字段在類中都有相應的Field
  • ActiveRecord同時負責把??持久化,在ActiveRecord中封裝了對數據庫的訪問,即 CURD;
  • ActiveRecord是?種領域模型(Domain Model),封裝了部分業務邏輯;

6.1、開啟AR之旅

MP 中,開啟 AR ?常簡單,只需要將實體對象繼承 Model 即可。 package com.lagou.mp.pojo; 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 com.baomidou.mybatisplus.extension.activerecord.Model; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor @AllArgsConstructor public class User extends Model<User> {private Long id;private String userName;private String password;private String name;private Integer age;private String email; }

6.2、根據主鍵查詢

@RunWith(SpringRunner.class) @SpringBootTest public class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testpublic void testAR() {User user = new User();user.setId(2L);User user2 = user.selectById();System.out.println(user2);} }

6.3、新增數據

@RunWith(SpringRunner.class) @SpringBootTest public class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testpublic void testARInsert() {User user = new User();user.setName("應顛");user.setAge(30);user.setEmail("yingdian@lagou.cn");boolean insert = user.insert();System.out.println(insert);} } [main] [com.lagou.mp.mapper.UserMapper.insert]-[DEBUG] == > Preparing: INSERT INTO tb_user ( name, age, email ) VALUES ( ?, ?, ?, ?, ? ) [main] [com.lagou.mp.mapper.UserMapper.insert]-[DEBUG] == > Parameters: 應癲 (String), 30 (Integer), liubei@lagou.cn(String) [main] [com.lagou.mp.mapper.UserMapper.insert]-[DEBUG] < == Updates: 1

6.4、更新操作

@RunWith(SpringRunner.class) @SpringBootTest public class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testpublic void testAR() {User user = new User();user.setId(8L);user.setAge(35);boolean update = user.updateById();System.out.println(update);} } 結果: [main] [com.lagou.mp.mapper.UserMapper.updateById]-[DEBUG] == > Preparing: UPDATE tb_user SET age = ? WHERE id = ? [main] [com.lagou.mp.mapper.UserMapper.updateById]-[DEBUG] == > Parameters: 35 (Integer), 8 (Long) [main] [com.lagou.mp.mapper.UserMapper.updateById]-[DEBUG] < == Updates: 1

6.5、刪除操作

@RunWith(SpringRunner.class) @SpringBootTest public class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testpublic void testAR() {User user = new User();user.setId(7L);boolean delete = user.deleteById();System.out.println(delete);} }

結果:

[main] [com.lagou.mp.mapper.UserMapper.deleteById]-[DEBUG] == > Preparing: DELETE FROM tb_user WHERE id = ? [main] [com.lagou.mp.mapper.UserMapper.deleteById]-[DEBUG] == > Parameters: 7 (Long) [main] [com.lagou.mp.mapper.UserMapper.deleteById]-[DEBUG] < == Updates: 1

6.6、根據條件查詢

@RunWith(SpringRunner.class) @SpringBootTest public class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testpublic void testARFindById() {User user = new User();QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();userQueryWrapper.le("age","20");List<User> users = user.selectList(userQueryWrapper);for (User user1 : users) {System.out.println(user1);}} } 結果: User (id = 1 , name = Jone, age = 18 , email = test1@baomidou.com) User (id = 2 , name = Jack, age = 20 , email = test2@baomidou.com) User (id = 7 , name = ?慕 , age = 18 , email = test@lagou.cn)

7. 插件

7.1mybatis的插件機制

MyBatis 允許你在已映射語句執?過程中的某?點進?攔截調?。默認情況下, MyBatis 允許使?插件 來攔截的?法調?包括: 1. Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed) 2. ParameterHandler (getParameterObject, setParameters) 3. ResultSetHandler (handleResultSets, handleOutputParameters) 4. StatementHandler (prepare, parameterize, batch, update, query) 我們看到了可以攔截 Executor 接?的部分?法,?如 update query commit rollback 等?法,還有其他接?的?些?法等。 總體概括為: 1. 攔截執?器的?法 2. 攔截參數的處理 3. 攔截結果集的處理 4. 攔截 Sql 語法構建的處理 攔截器示例: package com.lagou.mp.plugins; import org.apache.ibatis.executor.Executor; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.plugin.*; import java.util.Properties; @Intercepts({@Signature(type= Executor.class,method = "update",args = {MappedStatement.class,Object.class})}) public class MyInterceptor implements Interceptor {@Overridepublic Object intercept(Invocation invocation) throws Throwable {//攔截?法,具體業務邏輯編寫的位置return invocation.proceed();}@Overridepublic Object plugin(Object target) {//創建target對象的代理對象,?的是將當前攔截器加?到該對象中return Plugin.wrap(target, this);}@Overridepublic void setProperties(Properties properties) {//屬性設置} }

注?到Spring容器:

/*** ?定義攔截器*/@Beanpublic MyInterceptor myInterceptor(){return new MyInterceptor();}

或者通過xml配置,mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration><plugins><plugin interceptor="com.lagou.mp.plugins.MyInterceptor"></plugin></plugins> </configuration>

7.2、執?分析插件

MP 中提供了對 SQL 執?的分析的插件,可?作阻斷全表更新、刪除的操作,注意:該插件僅適?于開發環境,不適?于?產環境。 SpringBoot 配置: @Bean public SqlExplainInterceptor sqlExplainInterceptor(){SqlExplainInterceptor sqlExplainInterceptor = new SqlExplainInterceptor();List<ISqlParser> sqlParserList = new ArrayList<>();// 攻擊 SQL 阻斷解析器、加?解析鏈sqlParserList.add(new BlockAttackSqlParser());sqlExplainInterceptor.setSqlParserList(sqlParserList);return sqlExplainInterceptor; } 測試: @Test public void testUpdate(){User user = new User();user.setAge(20);int result = this.userMapper.update(user, null);System.out.println("result = " + result); } 結果: Caused by: com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: Prohibition of table update operation at com.baomidou.mybatisplus.core.toolkit.ExceptionUtils.mpe(ExceptionUtils.java:4 9) at com.baomidou.mybatisplus.core.toolkit.Assert.isTrue(Assert.java:38) at com.baomidou.mybatisplus.core.toolkit.Assert.notNull(Assert.java:72) at com.baomidou.mybatisplus.extension.parsers.BlockAttackSqlParser.processUpdate( BlockAttackSqlParser.java:45) at com.baomidou.mybatisplus.core.parser.AbstractJsqlParser.processParser(Abstract JsqlParser.java:92) at com.baomidou.mybatisplus.core.parser.AbstractJsqlParser.parser(AbstractJsqlPar ser.java:67) at com.baomidou.mybatisplus.extension.handlers.AbstractSqlParserHandler.sqlParser (AbstractSqlParserHandler.java:76) at com.baomidou.mybatisplus.extension.plugins.SqlExplainInterceptor.intercept(Sql ExplainInterceptor.java:63) at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:61) at com.sun.proxy. $Proxy70 .update(Unknown Source) at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession. java:197) ... 41 more 可以看到,當執?全表更新時,會拋出異常,這樣有效防?了?些誤操作。

7.3、性能分析插件

性能分析攔截器,?于輸出每條 SQL 語句及其執?時間,可以設置最?執?時間,超過時間會拋出異常。 該插件只?于開發環境,不建議?產環境使?。 配置: javaconfig ?式 @Bean public PerformanceInterceptor performanceInterceptor(){PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();performanceInterceptor.setMaxTime(100);performanceInterceptor.setFormat(true);return performanceInterceptor; } xml ?式 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration><plugins><!-- SQL 執?性能分析,開發環境使?,線上不推薦。 maxTime 指的是 sql 最?執?時 ? --><plugin interceptor="com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor "><property name="maxTime" value="100" /><!--SQL是否格式化 默認false--><property name="format" value="true" /></plugin></plugins> </configuration> 執?結果: Time 11 ms - ID com.lagou.mp.mapper.UserMapper.selectById Execute SQL SELECT id, user_name, password, name, age, email FROM tb_user WHERE id = 7 可以看到,執?時間為 11ms 。如果將 maxTime 設置為 1 ,那么,該操作會拋出異常。

7.4、樂觀鎖插件

7.4.1、主要適?場景

意圖: 當要更新?條記錄的時候,希望這條記錄沒有被別?更新 樂觀鎖實現?式:
  • 取出記錄時,獲取當前version
  • 更新時,帶上這個version
  • 執?更新時, set version = newVersion where version = oldVersion
  • 如果version不對,就更新失敗

7.4.2、插件配置

spring xml: <bean class="com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor" /> spring boot: @Bean public OptimisticLockerInterceptor optimisticLockerInterceptor() {return new OptimisticLockerInterceptor(); }

7.4.3、注解實體字段

需要為實體字段添加 @Version 注解。 第?步,為表添加 version 字段,并且設置初始值為 1 ALTER TABLE `tb_user` ADD COLUMN `version` int(10) NULL AFTER `email`; UPDATE `tb_user` SET `version`='1';

第?步,為User實體對象添加version字段,并且添加@Version注解:

@Version private Integer version;

7.4.4、測試

測試?例: @Test public void testUpdate(){User user = new User();user.setAge(30);user.setId(2L);user.setVersion(1); //獲取到version為1int result = this.userMapper.updateById(user);System.out.println("result = " + result); } 執??志: main] [com.baomidou.mybatisplus.extension.parsers.BlockAttackSqlParser]- [DEBUG] Original SQL: UPDATE tb_user SET age = ?, version = ? WHERE id = ? AND version = ? [main] [com.baomidou.mybatisplus.extension.parsers.BlockAttackSqlParser]- [DEBUG] parser sql: UPDATE tb_user SET age = ?, version = ? WHERE id = ? AND version = ? [main] [org.springframework.jdbc.datasource.DataSourceUtils]-[DEBUG] Fetching JDBC Connection from DataSource [main] [org.mybatis.spring.transaction.SpringManagedTransaction]-[DEBUG] JDBC Connection [HikariProxyConnection@540206885 wrapping com.mysql.jdbc.JDBC4Connection@27e0f2f5] will not be managed by Spring [main] [com.lagou.mp.mapper.UserMapper.updateById]-[DEBUG] == > Preparing: UPDATE tb_user SET age = ?, version = ? WHERE id = ? AND version = ? [main] [com.lagou.mp.mapper.UserMapper.updateById]-[DEBUG] == > Parameters: 30 (Integer), 2 (Integer), 2 (Long), 1 (Integer) [main] [com.lagou.mp.mapper.UserMapper.updateById]-[DEBUG] < == Updates: 1 [main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@30135202] result = 1 可以看到,更新的條件中有 version 條件,并且更新的 version 2 如果再次執?,更新則不成功。這樣就避免了多?同時更新時導致數據的不?致。

7.4.5、特別說明

  • ?持的數據類型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime
  • 整數類型下 newVersion = oldVersion + 1
  • newVersion 會回寫到 entity
  • 僅?持 updateById(id) update(entity, wrapper) ?法
  • update(entity, wrapper) ?法下, wrapper 不能復?!!!

8. Sql 注?器

我們已經知道,在 MP 中,通過 AbstractSqlInjector BaseMapper 中的?法注?到了 Mybatis 容器,這樣這些?法才可以正常執?。 那么,如果我們需要擴充 BaseMapper 中的?法,?該如何實現呢? 下?我們以擴展 findAll ?法為例進?學習。

8.1、編寫MyBaseMapper

package com.lagou.mp.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import java.util.List; public interface MyBaseMapper<T> extends BaseMapper<T> {List<T> findAll(); } 其他的 Mapper 都可以繼承該 Mapper ,這樣實現了統?的擴展。 如: package com.lagou.mp.mapper; import com.lagou.mp.pojo.User; public interface UserMapper extends MyBaseMapper<User> {User findById(Long id); }

8.2、編寫MySqlInjector

如果直接繼承 AbstractSqlInjector 的話,原有的 BaseMapper 中的?法將失效,所以我們選擇繼承 DefaultSqlInjector 進?擴展。 package com.lagou.mp.sqlInjector; import com.baomidou.mybatisplus.core.injector.AbstractMethod; import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector; import java.util.List; public class MySqlInjector extends DefaultSqlInjector {@Overridepublic List<AbstractMethod> getMethodList() {List<AbstractMethod> methodList = super.getMethodList();methodList.add(new FindAll());// 再擴充?定義的?法list.add(new FindAll());return methodList;} }

8.3、編寫FindAll

package com.lagou.mp.sqlInjector; import com.baomidou.mybatisplus.core.enums.SqlMethod; import com.baomidou.mybatisplus.core.injector.AbstractMethod; import com.baomidou.mybatisplus.core.metadata.TableInfo; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.mapping.SqlSource; public class FindAll extends AbstractMethod {@Overridepublic MappedStatement injectMappedStatement(Class<?> mapperClass, Class<? > modelClass, TableInfo tableInfo) {String sqlMethod = "findAll";String sql = "select * from " + tableInfo.getTableName();SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);return this.addSelectMappedStatement(mapperClass, sqlMethod, sqlSource, modelClass, tableInfo);} }

8.4、注冊到Spring容器

/** * ?定義SQL注?器 */ @Bean public MySqlInjector mySqlInjector(){return new MySqlInjector(); }

8.5、測試

@Test public void testFindAll(){List<User> users = this.userMapper.findAll();for (User user : users) {System.out.println(user);} } 輸出的 SQL [main] [com.lagou.mp.mapper.UserMapper.findAll]-[DEBUG] == > Preparing: select * from tb_user [main] [com.lagou.mp.mapper.UserMapper.findAll]-[DEBUG] == > Parameters: [main] [com.lagou.mp.mapper.UserMapper.findAll]-[DEBUG] < == Total: 10 ?此,我們實現了全局擴展 SQL 注?器。

9. ?動填充功能

有些時候我們可能會有這樣的需求,插?或者更新數據時,希望有些字段可以?動填充數據,?如密碼、version 等。在 MP 中提供了這樣的功能,可以實現?動填充。

9.1、添加@TableField注解

@TableField(fill = FieldFill.INSERT) //插?數據時進?填充 private String version; email 添加?動填充功能,在新增數據時有效。 FieldFill 提供了多種模式選擇: public enum FieldFill { 9.2、編寫MyMetaObjectHandler 9.3、測試/*** 默認不處理*/DEFAULT,/*** 插?時填充字段*/INSERT,/*** 更新時填充字段*/UPDATE,/*** 插?和更新時填充字段*/INSERT_UPDATE }

9.2、編寫MyMetaObjectHandler

package com.lagou.mp.handler; import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import org.apache.ibatis.reflection.MetaObject; import org.springframework.stereotype.Component; @Component public class MyMetaObjectHandler implements MetaObjectHandler {@Overridepublic void insertFill(MetaObject metaObject) {Object password = getFieldValByName("version", metaObject);if(null == password){//字段為空,可以進?填充setFieldValByName("version", "123456", metaObject);}}@Overridepublic void updateFill(MetaObject metaObject) {} }

9.3、測試

@Test public void testInsert(){User user = new User();user.setName("冰冰");user.setAge(30);user.setVersion(1);int result = this.userMapper.insert(user);System.out.println("result = " + result); } 結果:

10. 邏輯刪除

開發系統時,有時候在實現功能時,刪除操作需要實現邏輯刪除,所謂邏輯刪除就是將數據標記為刪除,?并?真正的物理刪除(?DELETE 操作),查詢時需要攜帶狀態條件,確保被標記的數據不被查詢到。這樣做的?的就是避免數據被真正的刪除。 MP 就提供了這樣的功能,?便我們使?,接下來我們?起學習下。

10.1、修改表結構

ALTER TABLE `tb_user` ADD COLUMN `deleted` int(1) NULL DEFAULT 0 COMMENT '1代表刪除,0代表未刪除' AFTER `version`; tb_user 表增加 deleted 字段,?于表示數據是否被刪除, 1 代表刪除, 0 代表未刪除。 同時,也修改 User 實體,增加 deleted 屬性并且添加 @TableLogic 注解: @TableLogic private Integer deleted;

10.2、配置

application.properties # 邏輯已刪除值(默認為 1) mybatis-plus.global-config.db-config.logic-delete-value=1 # 邏輯未刪除值(默認為 0) mybatis-plus.global-config.db-config.logic-not-delete-value=0

10.3、測試

@Test public void testDeleteById(){this.userMapper.deleteById(2L); } 執?的 SQL [main] [com.lagou.mp.mapper.UserMapper.deleteById]-[DEBUG] == > Preparing: UPDATE tb_user SET deleted = 1 WHERE id = ? AND deleted = 0 [main] [com.lagou.mp.mapper.UserMapper.deleteById]-[DEBUG] == > Parameters: 2 (Long) [main] [com.lagou.mp.mapper.UserMapper.deleteById]-[DEBUG] < == Updates: 1

測試查詢: @Test public void testSelectById(){User user = this.userMapper.selectById(2L);System.out.println(user); } 執?的 SQL [main] [com.lagou.mp.mapper.UserMapper.selectById]-[DEBUG] == > Preparing: SELECT id,user_name,password,name,age,email,version,deleted FROM tb_user WHERE id = ? AND deleted = 0 [main] [com.lagou.mp.mapper.UserMapper.selectById]-[DEBUG] == > Parameters: 2 (Long) [main] [com.lagou.mp.mapper.UserMapper.selectById]-[DEBUG] < == Total: 0 可?,已經實現了邏輯刪除。

11. 代碼?成器

AutoGenerator MyBatis-Plus 的代碼?成器,通過 AutoGenerator 可以快速?成 Entity Mapper Mapper XML Service Controller 等各個模塊的代碼,極?的提升了開發效率。

11.1、創建?程

pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.4.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.lagou</groupId><artifactId>lagou-mp-generator</artifactId><version>0.0.1-SNAPSHOT</version><name>lagou-mp-generator</name><description>Demo project for Spring Boot</description><properties><java.version>11</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--mybatis-plus的springboot?持--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.1.1</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.1.1</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId></dependency><!--mysql驅動--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--簡化代碼的?具包--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build> </project>

11.2、代碼

package com.lagou.mp.generator; import java.util.ArrayList; import java.util.List; import java.util.Scanner; import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException; import com.baomidou.mybatisplus.core.toolkit.StringPool; import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.generator.AutoGenerator; import com.baomidou.mybatisplus.generator.InjectionConfig; import com.baomidou.mybatisplus.generator.config.DataSourceConfig; import com.baomidou.mybatisplus.generator.config.FileOutConfig; import com.baomidou.mybatisplus.generator.config.GlobalConfig; import com.baomidou.mybatisplus.generator.config.PackageConfig; import com.baomidou.mybatisplus.generator.config.StrategyConfig; import com.baomidou.mybatisplus.generator.config.TemplateConfig; import com.baomidou.mybatisplus.generator.config.po.TableInfo; import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine; /** * <p> * mysql 代碼?成器演示例? * </p> */ public class MysqlGenerator {/*** <p>* 讀取控制臺內容* </p>*/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.isNotEmpty(ipt)) {return ipt;}}throw new MybatisPlusException("請輸?正確的" + tip + "!");}/*** RUN THIS*/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.setAuthor("lagou");gc.setOpen(false);mpg.setGlobalConfig(gc);// 數據源配置DataSourceConfig dsc = new DataSourceConfig();dsc.setUrl("jdbc:mysql://127.0.0.1:3306/mp? useUnicode=true&useSSL=false&characterEncoding=utf8");// dsc.setSchemaName("public");dsc.setDriverName("com.mysql.jdbc.Driver");dsc.setUsername("root");dsc.setPassword("root");mpg.setDataSource(dsc);// 包配置PackageConfig pc = new PackageConfig();pc.setModuleName(scanner("模塊名"));pc.setParent("com.lagou.mp.generator");mpg.setPackageInfo(pc);// ?定義配置InjectionConfig cfg = new InjectionConfig() {@Overridepublic void initMap() {// to do nothing}};List<FileOutConfig> focList = new ArrayList<>();focList.add(new FileOutConfig("/templates/mapper.xml.ftl") {@Overridepublic String outputFile(TableInfo tableInfo) {// ?定義輸??件名稱return projectPath + "/lagou-mpgenerator/src/main/resources/mapper/" + pc.getModuleName()+ "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;}});cfg.setFileOutConfigList(focList);mpg.setCfg(cfg);mpg.setTemplate(new TemplateConfig().setXml(null));// 策略配置StrategyConfig strategy = new StrategyConfig();strategy.setNaming(NamingStrategy.underline_to_camel);strategy.setColumnNaming(NamingStrategy.underline_to_camel); //strategy.setSuperEntityClass("com.baomidou.mybatisplus.samples.generator.common.BaseEntity");strategy.setEntityLombokModel(true); //strategy.setSuperControllerClass("com.baomidou.mybatisplus.samples.generator.common.BaseController");strategy.setInclude(scanner("表名"));strategy.setSuperEntityColumns("id");strategy.setControllerMappingHyphenStyle(true);strategy.setTablePrefix(pc.getModuleName() + "_");mpg.setStrategy(strategy);// 選擇 freemarker 引擎需要指定如下加,注意 pom 依賴必須有!mpg.setTemplateEngine(new FreemarkerTemplateEngine());mpg.execute();} }

11.3、測試

代碼已?成:

實體對象:

12. MybatisX 快速開發插件

MybatisX 是?款基于 IDEA 的快速開發插件,為效率??。 安裝?法:打開 IDEA ,進? File -> Settings -> Plugins -> Browse Repositories ,輸? mybatisx 搜索并安裝。 功能:
  • Java XML 調回跳轉
  • Mapper ?法?動?成 XML

?

?

總結

以上是生活随笔為你收集整理的Mybatis-Plus 详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。