Mybatis_plus基礎教程(總結篇)
官網網址:http://mp.baomidou.com/參考教程:http://mp.baomidou.com/guide/
二.特性無侵入:只做增強不做改變,引入它不會對現有工程產生影響,如絲般順滑損耗小:啟動即會自動注入基本 CURD,性能基本無損耗,直接面向對象操作強大的 CRUD 操作:內置通用 Mapper、通用 Service,僅僅通過少量配置即可實現單表大部分 CRUD 操作,更有強大的條件構造器,滿足各類使用需求支持 Lambda 形式調用:通過 Lambda 表達式,方便的編寫各類查詢條件,無需再擔心字段寫錯支持多種數據庫:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer2005、SQLServer 等多種數據庫支持主鍵自動生成:支持多達 4 種主鍵策略(內含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解決主鍵問題支持 XML 熱加載:Mapper 對應的 XML 支持熱加載,對于簡單的 CRUD 操作,甚至可以無 XML 啟動支持 ActiveRecord 模式:支持 ActiveRecord 形式調用,實體類只需繼承 Model 類即可進行強大的 CRUD 操作支持自定義全局通用操作:支持全局通用方法注入( Write once, use anywhere )支持關鍵詞自動轉義:支持數據庫關鍵詞(order、key…)自動轉義,還可自定義關鍵詞內置代碼生成器:采用代碼或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 層代碼,支持模板引擎,更有超多自定義配置等您來使用內置分頁插件:基于 MyBatis 物理分頁,開發者無需關心具體操作,配置好插件之后,寫分頁等同于普通 List 查詢內置性能分析插件:可輸出 Sql 語句以及其執行時間,建議開發測試時啟用該功能,能快速揪出慢查詢內置全局攔截插件:提供全表 delete 、 update 操作智能分析阻斷,也可自定義攔截規則,預防誤操作內置 Sql 注入剝離器:支持 Sql 注入剝離,有效預防 Sql 注入攻擊
三.MyBatis_plus入門①創建并初始化數據庫mybatis_plus
②創建 User 表其表結構如下:
其對應的數據庫 Schema 腳本如下:
DROP TABLE IF EXISTS 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));
其對應的數據庫 Data 腳本如下:
DELETE FROM user;INSERT INTO user (id, name, age, email) VALUES(1, ’Jone’, 18, ’[email protected]’),(2, ’Jack’, 20, ’[email protected]’),(3, ’Tom’, 28, ’[email protected]’),(4, ’Sandy’, 21, ’[email protected]’),(5, ’Billie’, 24, ’[email protected]’);四.初始化工程
使用 Spring Initializr 快速初始化一個 Spring Boot 工程
Group:com.atguiguArtifact:mybatis-plus版本:2.2.1.RELEASE
五.添加依賴①引入依賴spring-boot-starter、spring-boot-starter-test添加:mybatis-plus-boot-starter、MySQL、lombok、在項目中使用Lombok可以減少很多重復代碼的書寫。比如說getter/setter/toString等方法的編寫
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> <!--mybatis-plus--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.0.5</version> </dependency> <!--mysql--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!--lombok用來簡化實體類--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies>
注意:引入 MyBatis-Plus 之后請不要再次引入 MyBatis 以及 MyBatis-Spring,以避免因版本差異導致的問題。
②idea中安裝lombok插件1).idea2020版本
在 application.properties 配置文件中添加 MySQL 數據庫的相關配置:
mysql5:
#mysql數據庫連接spring.datasource.driver-class-name=com.mysql.jdbc.Driverspring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plusspring.datasource.username=rootspring.datasource.password=123456
mysql8以上(spring boot 2.1):注意:driver和url的變化
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driverspring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8spring.datasource.username=rootspring.datasource.password=123456
注意:1、這里的 url 使用了 ?serverTimezone=GMT%2B8 后綴,因為Spring Boot 2.1 集成了 8.0版本的jdbc驅動,這個版本的 jdbc 驅動需要添加這個后綴,否則運行測試用例報告如下錯誤:
java.sql.SQLException: The server time zone value ‘Öйú±ê׼ʱ¼ä’ is unrecognized or represents more
2、這里的 driver-class-name 使用了 com.mysql.cj.jdbc.Driver ,在 jdbc 8 中 建議使用這個驅動,之前的 com.mysql.jdbc.Driver 已經被廢棄,否則運行測試用例的時候會有 WARN 信息
七.編寫代碼①主類在 Spring Boot 啟動類中添加 @MapperScan 注解,掃描 Mapper 文件夾注意:掃描的包名根據實際情況修改
@SpringBootApplication@MapperScan('com.mybatisplus.mapper')public class MybatisPlusApplication { ......}
②實體創建包 entity 編寫實體類 User.java(此處使用了 Lombok 簡化代碼)
//@Data:該注解使用在類上,該注解會提供getter、setter、equals、canEqual、hashCode、toString方法。@Datapublic class User { private Long id; private String name; private Integer age; private String email;}
@Data:該注解使用在類上,該注解會提供getter、setter、equals、canEqual、hashCode、toString方法。Lombok使用參考:https://blog.csdn.net/motui/article/details/79012846
③mapper
創建包 mapper 編寫Mapper 接口: UserMapper.java
public interface UserMapper extends BaseMapper<User> { }八.開始使用
添加測試類,進行功能測試:
@SpringBootTestpublic class MybatisPlusApplicationTests { @Autowired private UserMapper userMapper; @Test public void testSelectList() { System.out.println(('----- selectAll method test ------')); //UserMapper 中的 selectList() 方法的參數為 MP 內置的條件封裝器 Wrapper //所以不填寫就是無任何條件 List<User> users = userMapper.selectList(null); users.forEach(System.out::println); }}
注意:
IDEA在 userMapper 處報錯,因為找不到注入的對象,因為類是動態創建的,但是程序可以正確的執行。
為了避免報錯,可以在 dao 層 的接口上添加----- @Repository 注
控制臺輸出:
User(id=1, name=Jone, age=18, [email protected])User(id=2, name=Jack, age=20, [email protected])User(id=3, name=Tom, age=28, [email protected])User(id=4, name=Sandy, age=21, [email protected])User(id=5, name=Billie, age=24, [email protected])
通過以上幾個簡單的步驟,我們就實現了 User 表的 CRUD 功能,甚至連 XML 文件都不用編寫!
九.配置日志查看sql輸出日志:在application.properties中加:
#mybatis日志mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
在輸出臺中就有日志了
(1)ID_WORKERMyBatis-Plus默認的主鍵策略是:ID_WORKER 全局唯一ID參考資料:分布式系統唯一ID生成方案匯總:https://www.cnblogs.com/haoxinyue/p/5208136.html
(2)自增策略要想主鍵自增需要配置如下主鍵策略①.需要在創建數據表的時候設置主鍵自增實體字段中配置 @TableId(type = IdType.AUTO)
在User實體類中的id 上加
@TableId(type = IdType.AUTO)private Long id;
要想影響所有實體的配置,可以設置全局主鍵配置
#全局設置主鍵生成策略mybatis-plus.global-config.db-config.id-type=auto
其它主鍵策略:分析 IdType 源碼可知
@Getterpublic enum IdType { /** * 數據庫ID自增 */ AUTO(0), /** * 該類型為未設置主鍵類型 */ NONE(1), /** * 用戶輸入ID * 該類型可以通過自己注冊自動填充插件進行填充 */ INPUT(2), /* 以下3種類型、只有當插入對象ID 為空,才自動填充。 */ /** * 全局唯一ID (idWorker) */ ID_WORKER(3), /** * 全局唯一ID (UUID) */ UUID(4), /** * 字符串全局唯一ID (idWorker 的字符串表示) */ ID_WORKER_STR(5); private int key; IdType(int key) { this.key = key; }}2.插入操作
在User實體類中加
//@TableId:MyBatis-Plus默認的主鍵策略是:ID_WORKER 全局唯一ID @TableId(type = IdType.ID_WORKER) private Long id;
在測試類中
public class MybatisPlusApplicationTests { @Autowired private UserMapper userMapper; public void testInsert(){ User user = new User(); user.setName('Helen'); user.setAge(18); user.setEmail('[email protected]'); int result = userMapper.insert(user); System.out.println(result); //影響的行數 System.out.println(user); //id自動回填 }
注意:數據庫插入id值默認為:全局唯一id
1、根據Id更新操作**注意:**update時生成的sql自動是動態sql:UPDATE user SET age=? WHERE id=?
@Test public void testUpdateById(){ User user = new User(); user.setId(1L); user.setAge(28); int result = userMapper.updateById(user); System.out.println(result); }
2、自動填充項目中經常會遇到一些數據,每次都使用相同的方式填充,例如記錄的創建時間,更新時間等。我們可以使用MyBatis Plus的自動填充功能,完成這些字段的賦值工作:
(1)數據庫表中添加自動填充字段在User表中添加datetime類型的新的字段 create_time、update_time(2)實體上添加注解
@Datapublic class User { @TableId(type = IdType.ID_WORKER) private Long id; private String name; private Integer age; private String email;//在數據庫中是create_time 在User實體類中是createTime, _t自動轉換T @TableField( fill=FieldFill.INSERT) private Date createTime; @TableField(fill = FieldFill.INSERT_UPDATE) private Date updateTime; }
(3)實現元對象處理器接口注意:不要忘記添加 @Component 注解
package com.handler;import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;import org.apache.ibatis.reflection.MetaObject;import org.springframework.stereotype.Controller;import java.util.Date;@Component public class MyMetaObjectHandler implements MetaObjectHandler { /** * 插入時時間 * @param metaObject */ @Override public void insertFill(MetaObject metaObject) { this.setFieldValByName('createTime',new Date(),metaObject); this.setFieldValByName('updateTime',new Date(),metaObject); } /** * 修改時時間 * @param metaObject */ @Override public void updateFill(MetaObject metaObject) { this.setFieldValByName('updateTime',new Date(),metaObject); }}
(4)再次運行 測試 結果
**主要適用場景:**當要更新一條記錄的時候,希望這條記錄沒有被別人更新,也就是說實現線程安全的數據更新樂觀鎖實現方式:
①取出記錄時,獲取當前version②更新時,帶上這個version③執行更新時, set version = newVersion where version = oldVersion④如果version不對,就更新失敗
(1)數據庫中添加version字段`在這里插入代碼片
ALTER TABLE `user` ADD COLUMN `version` INT
(2)實體類添加version字段 :并添加 @Version 注解
@TableField(fill = FieldFill.INSERT)3private Integer version;
(3)元對象處理器接口添加version的insert默認值
@Controllerpublic class MyMetaObjectHandler implements MetaObjectHandler { /** * 插入時時間 * @param metaObject */ @Override public void insertFill(MetaObject metaObject) { this.setFieldValByName('createTime',new Date(),metaObject); this.setFieldValByName('updateTime',new Date(),metaObject); //看這里 this.setFieldValByName('version',1,metaObject); } /** * 修改時時間 * @param metaObject */ @Override public void updateFill(MetaObject metaObject) { this.setFieldValByName('updateTime',new Date(),metaObject); }}
特別說明:
支持的數據類型只有 int,Integer,long,Long,Date,Timestamp,LocalDateTime整數類型下 newVersion = oldVersion + 1newVersion 會回寫到 entity 中僅支持 updateById(id) 與 update(entity, wrapper) 方法在 update(entity, wrapper) 方法下, wrapper 不能復用!!!
(4)在 MybatisPlusConfig 中注冊 Bean創建配置類
package com.config;import com.baomidou.mybatisplus.core.injector.ISqlInjector;import com.baomidou.mybatisplus.extension.injector.LogicSqlInjector;import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor;import org.mybatis.spring.annotation.MapperScan;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Profile;import org.springframework.stereotype.Controller;@Configuration@MapperScan('com.mapper')public class MyConfig { /** * 樂觀鎖插件 */ @Bean public OptimisticLockerInterceptor optimisticLockerInterceptor() { return new OptimisticLockerInterceptor(); } }
(5)測試樂觀鎖可以修改成功測試后分析打印的sql語句,將version的數值進行了加1操作
/** * 測試 樂觀鎖插件 */@Testpublic void testOptimisticLocker() { //查詢 User user = userMapper.selectById(1L); //修改數據 user.setName('Helen Yao'); user.setEmail('[email protected]'); //執行更新 userMapper.updateById(user);}
(5)測試樂觀鎖修改失敗
/** * 測試樂觀鎖插件 失敗 */@Testpublic void testOptimisticLockerFail() { //查詢 User user = userMapper.selectById(1L); //修改數據 user.setName('Helen Yao1'); user.setEmail('[email protected]'); //模擬取出數據后,數據庫中version實際數據比取出的值大,即已被其它線程修改并更新了version user.setVersion(user.getVersion() - 1); //執行更新 userMapper.updateById(user);}5.select
1、根據id查詢記錄
@Testpublic void testSelectById(){ User user = userMapper.selectById(1L); System.out.println(user);}
2、通過多個id批量查詢完成了動態sql的foreach的功能
@Testpublic void testSelectBatchIds(){ List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3)); users.forEach(System.out::println);}
3、簡單的條件查詢通過map封裝查詢條件(不怎么用 看看就行)
@Testpublic void testSelectByMap(){ HashMap<String, Object> map = new HashMap<>(); map.put('name', 'Helen'); map.put('age', 18); List<User> users = userMapper.selectByMap(map); users.forEach(System.out::println);}
**注意:**map中的key對應的是數據庫中的列名。例如數據庫user_id,實體類是userId,這時map的key需要填寫user_id
4、分頁MyBatis Plus自帶分頁插件,只要簡單的配置即可實現分頁功能(1)創建配置類此時可以刪除主類中的 @MapperScan 掃描注解
@Configuration@MapperScan('com.mapper')public class MyConfig { /** * 分頁插件 */ @Bean public PaginationInterceptor paginationInterceptor() { return new PaginationInterceptor(); } }
(2)測試selectPage分頁(自己用的)測試:最終通過page對象獲取相關數據
/** * 分頁查詢 */ @Test void pages(){ //1.創建page對象 //傳入兩個參數:當前 頁 和 每頁顯示記錄數 Page<User> page=new Page<User>(1,5); //調用mp分頁查詢的方法 //調用mp分頁查詢過程中,底層封裝 //把分頁所有數據封裝到page對象里面 userMapper.selectPage(page,null); //通過page對象獲取分頁數據 System.out.println(page.getCurrent()); System.out.println(page.getRecords()); System.out.println(page.getSize()); System.out.println(page.getTotal()); System.out.println(page.getPages()); System.out.println(page.hasNext()); System.out.println(page.hasPrevious()); }
控制臺sql語句打印:SELECT id,name,age,email,create_time,update_time FROM user LIMIT 0,5
(3)測試selectMapsPage分頁:結果集是Map(zjd沒有用過)
@Testpublic void testSelectMapsPage() { Page<User> page = new Page<>(1, 5); IPage<Map<String, Object>> mapIPage = userMapper.selectMapsPage(page, null); //注意:此行必須使用 mapIPage 獲取記錄列表,否則會有數據類型轉換錯誤 mapIPage.getRecords().forEach(System.out::println); System.out.println(page.getCurrent()); System.out.println(page.getPages()); System.out.println(page.getSize()); System.out.println(page.getTotal()); System.out.println(page.hasNext()); System.out.println(page.hasPrevious());}6.delete
1、根據id刪除記錄
@Testpublic void testDeleteById(){ int result = userMapper.deleteById(8L); System.out.println(result);}
2、批量刪除
@Test public void testDeleteBatchIds() { int result = userMapper.deleteBatchIds(Arrays.asList(8, 9, 10)); System.out.println(result); }
3、簡單的條件查詢刪除
@Testpublic void testDeleteByMap() { HashMap<String, Object> map = new HashMap<>(); map.put('name', 'Helen'); map.put('age', 18); int result = userMapper.deleteByMap(map); System.out.println(result);}
4、*邏輯刪除
物理刪除:真實刪除,將對應數據從數據庫中刪除,之后查詢不到此條被刪除數據邏輯刪除:假刪除,將對應數據中代表是否被刪除字段狀態修改為“被刪除狀態”,之后在數據庫中仍舊能看到此條數據記錄(1)數據庫中添加 deleted字段
ALTER TABLE `user` ADD COLUMN `deleted` boolean
(2)實體類添加deleted 字段并加上 @TableLogic 注解 和 @TableField(fill = FieldFill.INSERT) 注解
@TableLogic@TableField(fill = FieldFill.INSERT)private Integer deleted;
(3)元對象處理器接口添加deleted的insert默認值
@Controllerpublic class MyMetaObjectHandler implements MetaObjectHandler { /** * 插入時時間 * @param metaObject */ @Override public void insertFill(MetaObject metaObject) { this.setFieldValByName('createTime',new Date(),metaObject); this.setFieldValByName('updateTime',new Date(),metaObject); this.setFieldValByName('version',1,metaObject); //看這里******** this.setFieldValByName('deleted',0,metaObject); } /** * 修改時時間 * @param metaObject */ @Override public void updateFill(MetaObject metaObject) { this.setFieldValByName('updateTime',new Date(),metaObject); }}
(4)application.properties 加入配置此為默認值,如果你的默認值和mp默認的一樣,該配置可無
mybatis-plus.global-config.db-config.logic-delete-value=1mybatis-plus.global-config.db-config.logic-not-delete-value=0
(5)在 MyConfig 中注冊 Bean
@Beanpublic ISqlInjector sqlInjector() { return new LogicSqlInjector();}
(6)測試邏輯刪除測試后發現,數據并沒有被刪除,deleted字段的值由0變成了1測試后分析打印的sql語句,是一條update**注意:**被刪除數據的deleted 字段的值必須是 0,才能被選取出來執行邏輯刪除的操作
/** * 測試 邏輯刪除 */@Testpublic void testLogicDelete() { int result = userMapper.deleteById(1L); System.out.println(result);}
(7)測試邏輯刪除后的查詢MyBatis Plus中查詢操作也會自動添加邏輯刪除字段的判斷
/** * 測試 邏輯刪除后的查詢: * 不包括被邏輯刪除的記錄 */@Testpublic void testLogicDeleteSelect() { User user = new User(); List<User> users = userMapper.selectList(null); users.forEach(System.out::println);}
測試后分析打印的sql語句,包含 WHERE deleted=0SELECT id,name,age,email,create_time,update_time,deleted FROM user WHERE deleted=0
7.性能分析性能分析攔截器,用于輸出每條 SQL 語句及其執行時間SQL 性能執行分析,開發環境使用,超過指定時間,停止運行。有助于發現問題
1、配置插件(1)參數說明參數:maxTime: SQL 執行最大時長,超過自動停止運行,有助于發現問題。參數:format: SQL是否格式化,默認false。(2)在 MyConfig 中配置
/** * SQL 執行性能分析插件 * 開發環境使用,線上不推薦。 maxTime 指的是 sql 最大執行時長 * * 三種環境 *dev: 開發環境 * test: 測試環境 * prod: 生產環境 * * */ @Bean @Profile({'dev','test'})// 設置 dev test 環境開啟 public PerformanceInterceptor performanceInterceptor() { PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor(); performanceInterceptor.setMaxTime(500);//ms/毫秒,超過此處設置的ms則sql不執行 performanceInterceptor.setFormat(true); return performanceInterceptor; }
(3)Spring Boot 中設置dev環境
#環境設置:dev、test、prodspring.profiles.active=dev
2、測試(1)常規測試
/** * 測試 性能分析插件 */@Testpublic void testPerformance() { User user = new User(); user.setName('我是Helen'); user.setEmail('[email protected]'); user.setAge(18); userMapper.insert(user);}
輸出:
(2)將maxTime 改小之后再次進行測試
performanceInterceptor.setMaxTime(5);//ms,超過此處設置的ms不執行
如果執行時間過長,則拋出異常:The SQL execution time is too large,輸出:
如果想進行復雜條件查詢,那么需要使用條件構造器 Wapper,涉及到如下方法1、delete2、selectOne3、selectCount4、selectList5、selectMaps6、selectObjs7、update
十一.條件構造器_wapper介紹 1.wapper介紹Wrapper : 條件構造抽象類,最頂端父類AbstractWrapper : 用于查詢條件封裝,生成 sql 的 where 條件QueryWrapper : Entity 對象封裝操作類,不是用lambda語法UpdateWrapper : Update 條件封裝,用于Entity對象更新操作AbstractLambdaWrapper : Lambda 語法使用 Wrapper統一處理解析 lambda 獲取 column。LambdaQueryWrapper :看名稱也能明白就是用于Lambda語法使用的查詢WrapperLambdaUpdateWrapper : Lambda 更新封裝Wrapper
2.AbstractWrapper注意:以下條件構造器的方法入參中的 column 均表示數據庫字段1、ge、gt、le、lt、isNull、isNotNull
@Testpublic void testDelete() { QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper .isNull('name') .ge('age', 12) .isNotNull('email'); int result = userMapper.delete(queryWrapper); System.out.println('delete return count = ' + result);}
SQL:UPDATE user SET deleted=1 WHERE deleted=0 AND name IS NULL AND age >= ? AND email IS NOT NULL
2、eq、ne注意:seletOne 返回的是一條實體記錄,當出現多條時會報錯
@Testpublic void testSelectOne() { QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.eq('name', 'Tom'); User user = userMapper.selectOne(queryWrapper); System.out.println(user);}
SELECT id,name,age,email,create_time,update_time,deleted,version FROM user WHERE deleted=0 AND name = ?3、between、notBetween包含大小邊界
@Testpublic void testSelectCount() { QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.between('age', 20, 30); Integer count = userMapper.selectCount(queryWrapper); System.out.println(count);}
SELECT COUNT(1) FROM user WHERE deleted=0 AND age BETWEEN ? AND ?4、allEq
@Testpublic void testSelectList() { QueryWrapper<User> queryWrapper = new QueryWrapper<>(); Map<String, Object> map = new HashMap<>(); map.put('id', 2); map.put('name', 'Jack'); map.put('age', 20); queryWrapper.allEq(map); List<User> users = userMapper.selectList(queryWrapper); users.forEach(System.out::println);}
SELECT id,name,age,email,create_time,update_time,deleted,versionFROM user WHERE deleted=0 AND name = ? AND id = ? AND age = ?
5、like、notLike、likeLeft、likeRightselectMaps返回Map集合列表
@Testpublic void testSelectMaps() { QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper .notLike('name', 'e') .likeRight('email', 't'); List<Map<String, Object>> maps = userMapper.selectMaps(queryWrapper);//返回值是Map列表 maps.forEach(System.out::println);}
SELECT id,name,age,email,create_time,update_time,deleted,versionFROM user WHERE deleted=0 AND name NOT LIKE ? AND email LIKE ?
6、in、notIn、inSql、notinSql、exists、notExists
in、notIn:①notIn(“age”,{1,2,3})—>age not in (1,2,3)②notIn(“age”, 1, 2, 3)—>age not in (1,2,3)inSql、notinSql:可以實現子查詢①例: inSql(“age”, “1,2,3,4,5,6”)—>age in (1,2,3,4,5,6)②例: inSql(“id”, “select id from table where id < 3”)—>id in (select id from table where id < 3)
@Testpublic void testSelectObjs() { QueryWrapper<User> queryWrapper = new QueryWrapper<>(); //queryWrapper.in('id', 1, 2, 3); queryWrapper.inSql('id', 'select id from user where id < 3'); List<Object> objects = userMapper.selectObjs(queryWrapper);//返回值是Object列表 objects.forEach(System.out::println);}
SELECT id,name,age,email,create_time,update_time,deleted,versionFROM user WHERE deleted=0 AND id IN (select id from user where id < 3)
7、or、and注意:這里使用的是 UpdateWrapper不調用or則默認為使用 and 連
@Testpublic void testUpdate1() { //修改值 User user = new User(); user.setAge(99); user.setName('Andy'); //修改條件 UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>(); userUpdateWrapper .like('name', 'h') .or() .between('age', 20, 30); int result = userMapper.update(user, userUpdateWrapper); System.out.println(result);}
UPDATE user SET name=?, age=?, update_time=? WHERE deleted=0 AND name LIKE ? OR age BETWEEN ? AND ?
8、嵌套or、嵌套and這里使用了lambda表達式,or中的表達式最后翻譯成sql時會被加上圓括號
@Testpublic void testUpdate2() { //修改值 User user = new User(); user.setAge(99); user.setName('Andy'); //修改條件 UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>(); userUpdateWrapper .like('name', 'h') .or(i -> i.eq('name', '李白').ne('age', 20)); int result = userMapper.update(user, userUpdateWrapper); System.out.println(result);}
UPDATE user SET name=?, age=?, update_time=?WHERE deleted=0 AND name LIKE ?OR ( name = ? AND age <> ? )
9、orderBy、orderByDesc、orderByAsc
@Testpublic void testSelectListOrderBy() { QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.orderByDesc('id'); List<User> users = userMapper.selectList(queryWrapper); users.forEach(System.out::println);}
SELECT id,name,age,email,create_time,update_time,deleted,versionFROM user WHERE deleted=0 ORDER BY id DESC
10、last直接拼接到 sql 的最后注意:只能調用一次,多次調用以最后一次為準 有sql注入的風險,請謹慎使用
@Testpublic void testSelectListLast() { QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.last('limit 1'); List<User> users = userMapper.selectList(queryWrapper); users.forEach(System.out::println);}
}SELECT id,name,age,email,create_time,update_time,deleted,versionFROM user WHERE deleted=0 limit 1
11、指定要查詢的列
@Testpublic void testSelectListColumn() { QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.select('id', 'name', 'age'); List<User> users = userMapper.selectList(queryWrapper); users.forEach(System.out::println);}
SELECT id,name,age FROM user WHERE deleted=0
12、set、setSql最終的sql會合并 user.setAge(),以及 userUpdateWrapper.set() 和 setSql() 中 的字段
@Testpublic void testUpdateSet() { //修改值 User user = new User(); user.setAge(99); //修改條件 UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>(); userUpdateWrapper .like('name', 'h') .set('name', '老李頭')//除了可以查詢還可以使用set設置修改的字段 .setSql(' email = ’[email protected]’');//可以有子查詢 int result = userMapper.update(user, userUpdateWrapper);}
UPDATE user SET age=?, update_time=?, name=?, email = ‘[email protected]’ WHERE deleted=0 AND name LIKE ?
(自己打的)
//mp實現復雜查詢操作 @Test public void testSelectQuery() { //創建QueryWrapper對象 QueryWrapper<User> wrapper = new QueryWrapper<>(); //通過QueryWrapper設置條件 //ge、gt、le、lt //查詢age>=30記錄 //第一個參數字段名稱,第二個參數設置值 wrapper.ge('age',30); //eq:等于、ne:不等于 //wrapper.eq('name','lilei'); //wrapper.ne('name','lilei'); //between:兩者之間 //查詢年齡 20-30 // wrapper.between('age',20,30); //like //wrapper.like('name','岳'); //orderByDesc // wrapper.orderByDesc('id'); //last //wrapper.last('limit 1'); //指定要查詢的列// wrapper.select('id','name'); List<User> users = userMapper.selectList(wrapper); for (User user : users) { System.out.println(user); } }
總結
到此這篇關于Mybatis_plus基礎教程(總結篇)的文章就介紹到這了,更多相關Mybatis plus基礎內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!
相關文章:
