Mybatis-Plus 详解 拉钩笔记
目錄
1. Mybatis-Plus概念
1.1 Mybatis-Plus介紹
1.3 架構(gòu)
1.4 作者
2. Mybatis-Plus快速??
2.1 安裝
2.2 創(chuàng)建數(shù)據(jù)庫以及表
2.3 創(chuàng)建?程
2.4 Mybatis + MP
2.5 Spring + Mybatis + MP
2.6 SpringBoot + Mybatis + MP
3. 通?CRUD
3.1 插?操作
3.2 更新操作
3.3 刪除操作
3.3.4、deleteBatchIds
3.4 查詢操作
3.4.1、selectById
3.4.2、selectBatchIds
3.4.3、selectOne
3.4.4、selectCount
3.4.5、selectList
3.4.6、selectPage
3.5 SQL注?的原理
4. 配置
4.1、基本配置
4.1.1、configLocation
4.1.2、mapperLocations
4.1.3、typeAliasesPackage ?
4.2、進階配置
4.2.1、mapUnderscoreToCamelCase
4.2.2、cacheEnabled
4.3、DB 策略配置
4.3.1、idType
4.3.2、tablePrefix
5. 條件構(gòu)造器
5.1、allEq
5.1.1、說明
5.1.2、測試?例
5.2、基本?較操作
5.3、模糊查詢
5.4、排序
5.6、select
6. ActiveRecord
6.1、開啟AR之旅
6.3、新增數(shù)據(jù)
?編輯?
6.4、更新操作
?編輯
6.5、刪除操作
6.6、根據(jù)條件查詢
7. 插件
7.1、mybatis的插件機制
7.2、執(zhí)?分析插件
7.3、性能分析插件
7.4、樂觀鎖插件
7.4.1、主要適?場景
7.4.2、插件配置
7.4.3、注解實體字段
7.4.4、測試
7.4.5、特別說明
8. Sql 注?器
8.1、編寫MyBaseMapper
8.2、編寫MySqlInjector
8.3、編寫FindAll
8.4、注冊到Spring容器
8.5、測試
9. ?動填充功能
9.1、添加@TableField注解
9.2、編寫MyMetaObjectHandler
9.3、測試
10. 邏輯刪除
10.1、修改表結(jié)構(gòu)
10.2、配置
10.3、測試
11. 代碼?成器
11.1、創(chuàng)建?程
11.2、代碼
11.3、測試
12. MybatisX 快速開發(fā)插件
1. Mybatis-Plus概念
1.1 Mybatis-Plus介紹
官?: https://mybatis.plus/ 或 https://mp.baomidou.com/ Mybatis-Plus介紹 MyBatis-Plus(簡稱 MP)是?個 MyBatis 的增強?具,在 MyBatis 的基礎(chǔ)上只做增強不做改變,-為簡化開發(fā)、提?效率??。 愿景 我們的愿景是成為 MyBatis 最好的搭檔,就像 魂?羅 中的 1P、2P,基友搭配,效率翻倍。1.2 特性
- ?侵?:只做增強不做改變,引?它不會對現(xiàn)有?程產(chǎn)?影響,如絲般順滑
- 損耗?:啟動即會?動注?基本 CURD,性能基本?損耗,直接?向?qū)ο蟛僮?
- 強?的 CRUD 操作:內(nèi)置通? Mapper、通? Service,僅僅通過少量配置即可實現(xiàn)單表?部分CRUD 操作,更有強?的條件構(gòu)造器,滿?各類使?需求
- ?持 Lambda 形式調(diào)?:通過 Lambda 表達(dá)式,?便的編寫各類查詢條件,?需再擔(dān)?字段寫錯
- ?持主鍵?動?成:?持多達(dá) 4 種主鍵策略(內(nèi)含分布式唯? ID ?成器 - Sequence),可?由配置,完美解決主鍵問題
- ?持 ActiveRecord 模式:?持 ActiveRecord 形式調(diào)?,實體類只需繼承 Model 類即可進?強?的 CRUD 操作
- ?持?定義全局通?操作:?持全局通??法注?( Write once, use anywhere )
- 內(nèi)置代碼?成器:采?代碼或者 Maven 插件可快速?成 Mapper 、 Model 、 Service 、 Controller 層代碼,?持模板引擎,更有超多?定義配置等您來使?
- 內(nèi)置分?插件:基于 MyBatis 物理分?,開發(fā)者?需關(guān)?具體操作,配置好插件之后,寫分?等同于普通 List 查詢
- 分?插件?持多種數(shù)據(jù)庫:?持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、 Postgre、SQLServer 等多種數(shù)據(jù)庫
- 內(nèi)置性能分析插件:可輸出 Sql 語句以及其執(zhí)?時間,建議開發(fā)測試時啟?該功能,能快速揪出慢查詢
- 內(nèi)置全局?jǐn)r截插件:提供全表 delete 、 update 操作智能分析阻斷,也可?定義攔截規(guī)則,預(yù)防誤操作
1.3 架構(gòu)
1.4 作者
Mybatis-Plus是由baomidou(苞??)組織開發(fā)并且開源的,?前該組織?概有30?左右。 碼云地址:https://gitee.com/organizations/baomidou2. Mybatis-Plus快速??
2.1 安裝
全新的 MyBatis-Plus 3.0 版本基于 JDK8,提供了 lambda 形式的調(diào)?,所以安裝集成 MP3.0 要求 如下:- JDK 8+
- Maven or Gradle
2.2 創(chuàng)建數(shù)據(jù)庫以及表
創(chuàng)建User表,其表結(jié)構(gòu)如下: -- 創(chuàng)建測試表 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) ); -- 插?測試數(shù)據(jù) 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 創(chuàng)建?程
?導(dǎo)?依賴:
<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整合。 創(chuàng)建?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實現(xiàn)查詢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: 運?環(huán)境--><environments default="development"><environment id="development"><!--當(dāng)前的事務(wù)事務(wù)管理器是JDBC--><transactionManager type="JDBC"></transactionManager><!--數(shù)據(jù)源信息 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);}} } 測試結(jié)果: 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("指定數(shù)據(jù)庫表名") Mybatis+MP實現(xiàn)查詢User 第?步,將UserMapper繼承BaseMapper,將擁有了BaseMapper中的所有?法: import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.lagou.pojo.User; public interface UserMapper extends BaseMapper<User> { } 第?步,使?MP中的MybatisSqlSessionFactoryBuilder進程構(gòu)建: @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);// 可以調(diào)?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("指定數(shù)據(jù)庫表名") 簡單說明:- 由于使?了 MybatisSqlSessionFactoryBuilder進?了構(gòu)建,繼承的BaseMapper中的?法就載?到了SqlSession中,所以就可以直接使?相關(guān)的?法;
- 如圖
2.5 Spring + Mybatis + MP
引?了Spring框架,數(shù)據(jù)源、構(gòu)建等?作就交給了Spring管理。 創(chuàng)建?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> 實現(xiàn)查詢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,所以需要重新創(chuàng)建?程,并不是創(chuàng)建?Module。 創(chuàng)建?程 導(dǎo)?依賴 <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驅(qū)動--><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") //設(shè)置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
通過前?的學(xué)習(xí),我們了解到通過繼承BaseMapper就可以獲取到各種各樣的單表操作,接下來我們將詳細(xì)講解這些操作。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是受影響的?數(shù),并不是?增后的idint result = userMapper.insert(user);System.out.println(result);System.out.println(user.getId());} } 測試 1 1318744682116739074 可以看到,數(shù)據(jù)已經(jīng)寫?到了數(shù)據(jù)庫,但是,id的值不正確,我們期望的是數(shù)據(jù)庫?增?,實際是MP? 成了id的值寫?到了數(shù)據(jù)庫。 如何設(shè)置id的?成策略呢? MP?持的id策略: package com.baomidou.mybatisplus.annotation; import lombok.Getter; /** * ?成ID類型枚舉類 * * @author hubin * @since 2015-11-10 */ @Getter public enum IdType {/*** 數(shù)據(jù)庫ID?增*/AUTO(0),/*** 該類型為未設(shè)置主鍵類型*/NONE(1),/*** ?戶輸?ID* <p>該類型可以通過??注冊?動填充插件進?填充</p>*/INPUT(2),/* 以下3種類型、只有當(dāng)插?對象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; } 數(shù)據(jù)插?成功: @TableField 在MP中通過@TableField注解可以指定字段的?些屬性,常常解決的問題有2個: 1、對象中的屬性名和字段名不?致的問題(?駝峰) 2、對象中的屬性字段在表中不存在的問題 使?:?其他?法,如?字段不加?查詢字段:
?效果:
3.2 更新操作
在MP中,更新操作有2種,?種是根據(jù)id更新,另?種是根據(jù)條件更新。 根據(jù)id更新 ?法定義: /*** 根據(jù) 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); //更新的字段//根據(jù)id更新,更新不為null的字段this.userMapper.updateById(user);} } 結(jié)果: 根據(jù)條件更新 ?法定義: /*** 根據(jù) 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);//執(zhí)?更新操作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);//執(zhí)?更新操作int result = this.userMapper.update(null, wrapper);System.out.println("result = " + result);} 測試結(jié)果: [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 均可達(dá)到更新的效果。 關(guān)于wrapper更多的?法后?會詳細(xì)講解。3.3 刪除操作
deleteById ?法定義: /** * 根據(jù) 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() {//執(zhí)?刪除操作int result = this.userMapper.deleteById(6L);System.out.println("result = " + result);} }結(jié)果:
[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 數(shù)據(jù)被刪除。 deleteByMap ?法定義: /*** 根據(jù) 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中的元素設(shè)置為刪除的條件,多個之間為and關(guān)系int result = this.userMapper.deleteByMap(columnMap);System.out.println("result = " + result);} }結(jié)果:
[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 ?法定義: /** * 根據(jù) 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; 結(jié)果: 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);} }結(jié)果:
[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: 03.3.4、deleteBatchIds
?法定義: /*** 刪除(根據(jù)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() {//根據(jù)id集合批量刪除int result = this.userMapper.deleteBatchIds(Arrays.asList(1L,10L,20L));System.out.println("result = " + result);} } 結(jié)果: [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: 13.4 查詢操作
MP提供了多種查詢操作,包括根據(jù)id查詢、批量查詢、查詢單條數(shù)據(jù)、查詢列表、分?查詢等操作。3.4.1、selectById
?法定義: /*** 根據(jù) 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() {//根據(jù)id查詢數(shù)據(jù)User user = this.userMapper.selectById(2L);System.out.println("result = " + user);} } 結(jié)果: result = User(id=2, name=Jack, age=20, email=test2@baomidou.com)3.4.2、selectBatchIds
?法定義: /** * 查詢(根據(jù)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() {//根據(jù)id集合批量查詢List<User> users = this.userMapper.selectBatchIds(Arrays.asList(2L, 3L, 10L));for (User user : users) {System.out.println(user);}} } 結(jié)果: User(id=2, name=Jack, age=20, email=test2@baomidou.com) User(id=3, name=Tom, age=28, email=test3@baomidou.com)3.4.3、selectOne
?法定義: /** * 根據(jù) 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");//根據(jù)條件查詢?條數(shù)據(jù),如果結(jié)果超過?條會報錯User user = this.userMapper.selectOne(wrapper);System.out.println(user);} } 結(jié)果: User(id=2, name=Jack, age=20, email=test2@baomidou.com)3.4.4、selectCount
?法定義: /** * 根據(jù) Wrapper 條件,查詢總記錄數(shù) * * @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歲//根據(jù)條件查詢數(shù)據(jù)條數(shù)Integer count = this.userMapper.selectCount(wrapper);System.out.println("count = " + count);} } 結(jié)果: count = 23.4.5、selectList
?法定義: /** * 根據(jù) entity 條件,查詢?nèi)坑涗?* * @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歲//根據(jù)條件查詢數(shù)據(jù)List<User> users = this.userMapper.selectList(wrapper);for (User user : users) {System.out.println("user = " + user);}} } 結(jié)果: 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.6、selectPage
?法定義: /** * 根據(jù) entity 條件,查詢?nèi)坑涗?#xff08;并翻?) * * @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") //設(shè)置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);//根據(jù)條件查詢數(shù)據(jù)IPage<User> iPage = this.userMapper.selectPage(page, wrapper);System.out.println("數(shù)據(jù)總條數(shù):" + iPage.getTotal());System.out.println("總?數(shù):" + iPage.getPages());List<User> users = iPage.getRecords();for (User user : users) {System.out.println("user = " + user);}} }結(jié)果:
數(shù)據(jù)總條數(shù):4 總?數(shù):4 user = User(id=3, name=Tom, age=28, email=test3@baomidou.com)3.5 SQL注?的原理
前?我們已經(jīng)知道,MP在啟動后會將BaseMapper中的?系列的?法注冊到meppedStatements中, 那么究竟是如何注?的呢?流程?是怎么樣的?下?我們將?起來分析下。 在MP中,ISqlInjector負(fù)責(zé)SQL的注??作,它是?個接?,AbstractSqlInjector是它的實現(xiàn)類,實現(xiàn)關(guān)系如下: 在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);// 循環(huán)注??定義?法methodList.forEach(m -> m.inject(builderAssistant, mapperClass, modelClass, tableInfo));} else {logger.debug(mapperClass.toString() + ", No effective injection method was found.");}mapperRegistryCache.add(className);}} } 在實現(xiàn)?法中, methodList.forEach(m -> m.inject(builderAssistant, mapperClass, modelClass, tableInfo)); 是關(guān)鍵,循環(huán)遍歷?法,進?注?。 最終調(diào)?抽象?法injectMappedStatement進?真正的注?: /*** 注??定義 MappedStatement** @param mapperClass mapper 接?* @param modelClass mapper 泛型* @param tableInfo 數(shù)據(jù)庫表反射信息* @return MappedStatement*/public abstract MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo); 查看該?法的實現(xiàn): 以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.1、configLocation
MyBatis 配置?件位置,如果有單獨的 MyBatis 配置,請將其路徑配置到 configLocation 中。 MyBatis Configuration 的具體內(nèi)容請參考MyBatis 官??檔 Spring Boot: mybatis-plus.config-location = classpath:mybatis-config.xmlSpring MVC:
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean" ><property name="configLocation" value="classpath:mybatis-config.xml"/> </bean>4.1.2、mapperLocations
MyBatis Mapper 所對應(yīng)的 XML ?件位置,如果您在 Mapper 中有?定義?法(XML 中有?定義實現(xiàn)),需要進?該配置,告訴 Mapper 所對應(yīng)的 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);} } 運?結(jié)果:4.1.3、typeAliasesPackage ?
MyBaits 別名包掃描路徑,通過該屬性可以給包中的類注冊別名,注冊后在 Mapper 對應(yīng)的 XML ?件中可以直接使?類名,?不?使?全限定的類名(即 XML 中調(diào)?的時候不?包含包名)。 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.1、mapUnderscoreToCamelCase
- 類型: boolean
- 默認(rèn)值: true
4.2.2、cacheEnabled
- 類型: boolean
- 默認(rèn)值: true
4.3、DB 策略配置
4.3.1、idType
- 類型: com.baomidou.mybatisplus.annotation.IdType
- 默認(rèn)值: ID_WORKER
4.3.2、tablePrefix
- 類型: String
- 默認(rèn)值: null
5. 條件構(gòu)造器
在MP中,Wrapper接?的實現(xiàn)類關(guān)系如下: 可以看到,AbstractWrapper和AbstractChainWrapper是重點實現(xiàn),接下來我們重點學(xué)習(xí) AbstractWrapper以及其?類。 說明: QueryWrapper(LambdaQueryWrapper) 和 UpdateWrapper(LambdaUpdateWrapper) 的?類 ?于?成 sql 的 where 條件, entity 屬性也?于?成 sql 的 where 條件 注意: entity ?成的 where 條件與 使?各個 api ?成的 where 條件沒有任何關(guān)聯(lián)?為 官??檔地址:https://mybatis.plus/guide/wrapper.html5.1、allEq
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)
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<>();//設(shè)置條件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, ...)
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 '王%'
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
5.5、邏輯查詢
- or
- 拼接 OR
- 主動調(diào)? or 表示緊接著下?個?法不是? and 連接!(不調(diào)? or 則默認(rèn)為使? and 連接)
- and
- AND 嵌套
- 例: and(i -> i.eq("name", "李?").ne("status", "活著")) ---> and (name = '李?' and status <> '活著')
5.6、select
在MP查詢中,默認(rèn)查詢所有的字段,如果有需要也可以通過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)?直?受動態(tài)語?( PHP 、 Ruby 等)的喜愛,? Java 作為準(zhǔn)靜態(tài)語?,對于 ActiveRecord 往往只能感嘆其優(yōu)雅,所以我們也在 AR 道路上進?了?定的探索,希望?家能夠喜歡。? 什么是ActiveRecord? ActiveRecord也屬于ORM(對象關(guān)系映射)層,由Rails最早提出,遵循標(biāo)準(zhǔn)的ORM模型:表映射到記錄,記錄映射到對象,字段映射到對象屬性。配合遵循的命名和配置慣例,能夠很?程度的快速實現(xiàn)模型的操作,?且簡潔易懂。 ActiveRecord的主要思想是:- 每?個數(shù)據(jù)庫表對應(yīng)創(chuàng)建?個類,類的每?個對象實例對應(yīng)于數(shù)據(jù)庫中表的??記錄;通常 表的每個字段在類中都有相應(yīng)的Field;
- ActiveRecord同時負(fù)責(zé)把??持久化,在ActiveRecord中封裝了對數(shù)據(jù)庫的訪問,即 CURD;;
- ActiveRecord是?種領(lǐng)域模型(Domain Model),封裝了部分業(yè)務(wù)邏輯;
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、根據(jù)主鍵查詢
@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、新增數(shù)據(jù)
@RunWith(SpringRunner.class) @SpringBootTest public class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testpublic void testARInsert() {User user = new User();user.setName("應(yīng)顛");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: 應(yīng)癲 (String), 30(Integer), liubei@lagou.cn(String) [main] [com.lagou.mp.mapper.UserMapper.insert]-[DEBUG] <== Updates: 16.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);} } 結(jié)果: [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: 16.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);} }結(jié)果:
[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: 16.6、根據(jù)條件查詢
@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);}} } 結(jié)果: 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.1、mybatis的插件機制
MyBatis 允許你在已映射語句執(zhí)?過程中的某?點進?攔截調(diào)?。默認(rèn)情況下,MyBatis 允許使?插件 來攔截的?法調(diào)?包括: 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. 攔截執(zhí)?器的?法 2. 攔截參數(shù)的處理 3. 攔截結(jié)果集的處理 4. 攔截Sql語法構(gòu)建的處理 攔截器示例: 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 {//攔截?法,具體業(yè)務(wù)邏輯編寫的位置return invocation.proceed();}@Overridepublic Object plugin(Object target) {//創(chuàng)建target對象的代理對象,?的是將當(dāng)前攔截器加?到該對象中return Plugin.wrap(target, this);}@Overridepublic void setProperties(Properties properties) {//屬性設(shè)置} }注?到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、執(zhí)?分析插件
在MP中提供了對SQL執(zhí)?的分析的插件,可?作阻斷全表更新、刪除的操作,注意:該插件僅適?于開發(fā)環(huán)境,不適?于?產(chǎn)環(huán)境。 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); } 結(jié)果: 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 可以看到,當(dāng)執(zhí)?全表更新時,會拋出異常,這樣有效防?了?些誤操作。7.3、性能分析插件
性能分析攔截器,?于輸出每條 SQL 語句及其執(zhí)?時間,可以設(shè)置最?執(zhí)?時間,超過時間會拋出異常。 該插件只?于開發(fā)環(huán)境,不建議?產(chǎn)環(huán)境使?。 配置: 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 執(zhí)?性能分析,開發(fā)環(huán)境使?,線上不推薦。 maxTime 指的是 sql 最?執(zhí)?時 ? --><plugin interceptor="com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor "><property name="maxTime" value="100" /><!--SQL是否格式化 默認(rèn)false--><property name="format" value="true" /></plugin></plugins> </configuration> 執(zhí)?結(jié)果: 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 可以看到,執(zhí)?時間為11ms。如果將maxTime設(shè)置為1,那么,該操作會拋出異常。7.4、樂觀鎖插件
7.4.1、主要適?場景
意圖: 當(dāng)要更新?條記錄的時候,希望這條記錄沒有被別?更新 樂觀鎖實現(xiàn)?式:- 取出記錄時,獲取當(dāng)前version
- 更新時,帶上這個version
- 執(zhí)?更新時, 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字段,并且設(shè)置初始值為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); } 執(zhí)??志: 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。 如果再次執(zhí)?,更新則不成功。這樣就避免了多?同時更新時導(dǎo)致數(shù)據(jù)的不?致。7.4.5、特別說明
- ?持的數(shù)據(jù)類型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime
- 整數(shù)類型下 newVersion = oldVersion + 1
- newVersion 會回寫到 entity 中
- 僅?持 updateById(id) 與 update(entity, wrapper) ?法
- 在 update(entity, wrapper) ?法下, wrapper 不能復(fù)?!!!
8. Sql 注?器
我們已經(jīng)知道,在MP中,通過AbstractSqlInjector將BaseMapper中的?法注?到了Mybatis容器,這樣這些?法才可以正常執(zhí)?。 那么,如果我們需要擴充BaseMapper中的?法,?該如何實現(xiàn)呢? 下?我們以擴展findAll?法為例進?學(xué)習(xí)。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,這樣實現(xiàn)了統(tǒng)?的擴展。 如: 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 ?此,我們實現(xiàn)了全局?jǐn)U展SQL注?器。9. ?動填充功能
有些時候我們可能會有這樣的需求,插?或者更新數(shù)據(jù)時,希望有些字段可以?動填充數(shù)據(jù),?如密碼、version等。在MP中提供了這樣的功能,可以實現(xiàn)?動填充。9.1、添加@TableField注解
@TableField(fill = FieldFill.INSERT) //插?數(shù)據(jù)時進?填充 private String version; 為email添加?動填充功能,在新增數(shù)據(jù)時有效。 FieldFill提供了多種模式選擇: public enum FieldFill { 9.2、編寫MyMetaObjectHandler 9.3、測試/*** 默認(rèn)不處理*/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); } 結(jié)果:10. 邏輯刪除
開發(fā)系統(tǒng)時,有時候在實現(xiàn)功能時,刪除操作需要實現(xiàn)邏輯刪除,所謂邏輯刪除就是將數(shù)據(jù)標(biāo)記為刪除,?并?真正的物理刪除(?DELETE操作),查詢時需要攜帶狀態(tài)條件,確保被標(biāo)記的數(shù)據(jù)不被查詢到。這樣做的?的就是避免數(shù)據(jù)被真正的刪除。 MP就提供了這樣的功能,?便我們使?,接下來我們?起學(xué)習(xí)下。10.1、修改表結(jié)構(gòu)
ALTER TABLE `tb_user` ADD COLUMN `deleted` int(1) NULL DEFAULT 0 COMMENT '1代表刪除,0代表未刪除' AFTER `version`; 為tb_user表增加deleted字段,?于表示數(shù)據(jù)是否被刪除,1代表刪除,0代表未刪除。 同時,也修改User實體,增加deleted屬性并且添加@TableLogic注解: @TableLogic private Integer deleted;10.2、配置
application.properties: # 邏輯已刪除值(默認(rèn)為 1) mybatis-plus.global-config.db-config.logic-delete-value=1 # 邏輯未刪除值(默認(rèn)為 0) mybatis-plus.global-config.db-config.logic-not-delete-value=010.3、測試
@Test public void testDeleteById(){this.userMapper.deleteById(2L); } 執(zhí)?的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); } 執(zhí)?的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 可?,已經(jīng)實現(xiàn)了邏輯刪除。11. 代碼?成器
AutoGenerator 是 MyBatis-Plus 的代碼?成器,通過 AutoGenerator 可以快速?成 Entity、 Mapper、Mapper XML、Service、Controller 等各個模塊的代碼,極?的提升了開發(fā)效率。11.1、創(chuàng)建?程
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驅(qū)動--><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>* 讀取控制臺內(nèi)容* </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);// 數(shù)據(jù)源配置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 快速開發(fā)插件
MybatisX 是?款基于 IDEA 的快速開發(fā)插件,為效率??。 安裝?法:打開 IDEA,進? File -> Settings -> Plugins -> Browse Repositories,輸? mybatisx 搜索并安裝。 功能:- Java 與 XML 調(diào)回跳轉(zhuǎn)
- Mapper ?法?動?成 XML
?
?
總結(jié)
以上是生活随笔為你收集整理的Mybatis-Plus 详解 拉钩笔记的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 18个提高效率的办公软件推荐,收好不谢
- 下一篇: 【英语语法入门】 第31讲 [被动语态