01-MyBatisPlus簡介
一询枚、簡介
官網(wǎng):http://mp.baomidou.com/
參考教程:http://mp.baomidou.com/guide/
MyBatis-Plus(簡稱 MP)是一個(gè)?MyBatis?的增強(qiáng)工具,在 MyBatis 的基礎(chǔ)上只做增強(qiáng)不做改變冻押,為簡化開發(fā)、提高效率而生码荔。
二介返、特性
無侵入:只做增強(qiáng)不做改變星压,引入它不會(huì)對(duì)現(xiàn)有工程產(chǎn)生影響,如絲般順滑
損耗小:啟動(dòng)即會(huì)自動(dòng)注入基本 CURD溉知,性能基本無損耗陨瘩,直接面向?qū)ο蟛僮?/p>
強(qiáng)大的 CRUD 操作:內(nèi)置通用 Mapper、通用 Service级乍,僅僅通過少量配置即可實(shí)現(xiàn)單表大部分 CRUD 操作舌劳,更有強(qiáng)大的條件構(gòu)造器,滿足各類使用需求
支持 Lambda 形式調(diào)用:通過 Lambda 表達(dá)式玫荣,方便的編寫各類查詢條件甚淡,無需再擔(dān)心字段寫錯(cuò)
支持多種數(shù)據(jù)庫:支持 MySQL、MariaDB捅厂、Oracle贯卦、DB2、H2焙贷、HSQL撵割、SQLite、Postgre辙芍、SQLServer2005啡彬、SQLServer 等多種數(shù)據(jù)庫
支持主鍵自動(dòng)生成:支持多達(dá) 4 種主鍵策略(內(nèi)含分布式唯一 ID 生成器 - Sequence),可自由配置沸手,完美解決主鍵問題
支持 XML 熱加載:Mapper 對(duì)應(yīng)的 XML 支持熱加載外遇,對(duì)于簡單的 CRUD 操作,甚至可以無 XML 啟動(dòng)
支持 ActiveRecord 模式:支持 ActiveRecord 形式調(diào)用契吉,實(shí)體類只需繼承 Model 類即可進(jìn)行強(qiáng)大的 CRUD 操作
支持自定義全局通用操作:支持全局通用方法注入( Write once, use anywhere )
支持關(guān)鍵詞自動(dòng)轉(zhuǎn)義:支持?jǐn)?shù)據(jù)庫關(guān)鍵詞(order、key......)自動(dòng)轉(zhuǎn)義诡渴,還可自定義關(guān)鍵詞
內(nèi)置代碼生成器:采用代碼或者 Maven 插件可快速生成 Mapper 捐晶、 Model 菲语、 Service 、 Controller 層代碼惑灵,支持模板引擎山上,更有超多自定義配置等您來使用
內(nèi)置分頁插件:基于 MyBatis 物理分頁,開發(fā)者無需關(guān)心具體操作英支,配置好插件之后佩憾,寫分頁等同于普通 List 查詢
內(nèi)置性能分析插件:可輸出 Sql 語句以及其執(zhí)行時(shí)間,建議開發(fā)測試時(shí)啟用該功能干花,能快速揪出慢查詢
內(nèi)置全局?jǐn)r截插件:提供全表 delete 妄帘、 update 操作智能分析阻斷,也可自定義攔截規(guī)則池凄,預(yù)防誤操作
內(nèi)置 Sql 注入剝離器:支持 Sql 注入剝離抡驼,有效預(yù)防 Sql 注入攻擊
02-MyBatisPlus入門
快速開始參考:http://mp.baomidou.com/guide/quick-start.html
測試項(xiàng)目:?mybatis_plus
數(shù)據(jù)庫:mybatis_plus
一、創(chuàng)建并初始化數(shù)據(jù)庫
二肿仑、初始化工程
使用 Spring Initializr 快速初始化一個(gè) Spring Boot 工程
Group:com.atguigu
Artifact:mybatis-plus
版本:2.2.1.RELEASE
三致盟、添加依賴
1、引入依賴
spring-boot-starter尤慰、spring-boot-starter-test
添加:mybatis-plus-boot-starter馏锡、MySQL、lombok伟端、
在項(xiàng)目中使用Lombok可以減少很多重復(fù)代碼的書寫杯道。比如說getter/setter/toString等方法的編寫
2、idea中安裝lombok插件
setting-->plugins
四荔泳、配置
在?application.properties?配置文件中添加 MySQL 數(shù)據(jù)庫的相關(guān)配置:
mysql5
#mysql數(shù)據(jù)庫連接
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus
spring.datasource.username=root
spring.datasource.password=123456
mysql8以上(spring boot 2.1)
注意:driver和url的變化
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123456
注意:
1蕉饼、這里的?url?使用了??serverTimezone=GMT%2B8?后綴,因?yàn)镾pring Boot 2.1 集成了 8.0版本的jdbc驅(qū)動(dòng)玛歌,這個(gè)版本的 jdbc 驅(qū)動(dòng)需要添加這個(gè)后綴昧港,否則運(yùn)行測試用例報(bào)告如下錯(cuò)誤:
java.sql.SQLException: The server time zone value '?D1ú±ê×?ê±??' is unrecognized or represents more?
2、這里的?driver-class-name?使用了??com.mysql.cj.jdbc.Driver?支子,在 jdbc 8 中 建議使用這個(gè)驅(qū)動(dòng)创肥,之前的 com.mysql.jdbc.Driver 已經(jīng)被廢棄,否則運(yùn)行測試用例的時(shí)候會(huì)有 WARN 信息
五值朋、編寫代碼
1叹侄、主類
在 Spring Boot 啟動(dòng)類中添加?@MapperScan?注解,掃描 Mapper 文件夾
注意:掃描的包名根據(jù)實(shí)際情況修改
@SpringBootApplication
@MapperScan("com.atguigu.mybatisplus.mapper")
publicclassMybatisPlusApplication{
? ? ......
}
2昨登、實(shí)體
創(chuàng)建包?entity?編寫實(shí)體類?User.java(此處使用了?Lombok?簡化代碼)
@Data
publicclassUser{
????privateLongid;
????privateStringname;
????privateIntegerage;
????privateStringemail;
}
3趾代、mapper
創(chuàng)建包?mapper?編寫Mapper接口:UserMapper.java
package com.example.mpdemo.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;import com.example.mpdemo.entity.User;import org.springframework.stereotype.Repository;
@Repository
public interface UserMapper extends BaseMapper<User>{
}
六、開始使用
添加測試類丰辣,進(jìn)行功能測試
注意:
IDEA在 userMapper 處報(bào)錯(cuò)撒强,因?yàn)檎也坏阶⑷氲膶?duì)象禽捆,因?yàn)轭愂莿?dòng)態(tài)創(chuàng)建的,但是程序可以正確的執(zhí)行飘哨。
為了避免報(bào)錯(cuò)胚想,可以在 dao 層 的接口上添加?@Repository 注解。
七芽隆、配置日志
查看sql輸出日志
#mybatis日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
03-MyBatisPlus的CRUD 接口
一浊服、insert
1、插入操作
intresult=userMapper.insert(user);
注意:數(shù)據(jù)庫插入id值默認(rèn)為:全局唯一id
2胚吁、主鍵策略
(1)ID_WORKER
MyBatis-Plus默認(rèn)的主鍵策略是:ID_WORKER ?全局唯一ID
參考資料:分布式系統(tǒng)唯一ID生成方案匯總:https://www.cnblogs.com/haoxinyue/p/5208136.html
(2)自增策略
要想主鍵自增需要配置如下主鍵策略
? ? 需要在創(chuàng)建數(shù)據(jù)表的時(shí)候設(shè)置主鍵自增
? ? 實(shí)體字段中配置 @TableId(type = IdType.AUTO)
@TableId(type=IdType.AUTO)
private Longid;
要想影響所有實(shí)體的配置牙躺,可以設(shè)置全局主鍵配置
#全局設(shè)置主鍵生成策略
mybatis-plus.global-config.db-config.id-type=auto
其它主鍵策略:分析 IdType 源碼可知
@Getter
public enum IdType{
/**
* 數(shù)據(jù)庫ID自增
*/
AUTO(0),
/**
* 該類型為未設(shè)置主鍵類型
*/
NONE(1),
/**
* 用戶輸入ID
* 該類型可以通過自己注冊自動(dòng)填充插件進(jìn)行填充
*/
INPUT(2),
/* 以下3種類型、只有當(dāng)插入對(duì)象ID 為空囤采,才自動(dòng)填充述呐。 */
/**
* 全局唯一ID (idWorker)
*/
ID_WORKER(3),
/**
* 全局唯一ID (UUID)
*/
UUID(4),
/**
* 字符串全局唯一ID (idWorker 的字符串表示)
*/
ID_WORKER_STR(5);
private int key;
IdType(int key) {
????this.key=key;
?? }
}
二、update
1蕉毯、根據(jù)Id更新操作
注意:update時(shí)生成的sql自動(dòng)是動(dòng)態(tài)sql:UPDATE user SET age=? WHERE id=??
//修改操作
@Test
void updateUser() {
????User user =new User();
????user.setId(2L);
????user.setAge(120);
????int row =userMapper.updateById(user);
????System.out.println(row);
}
2乓搬、自動(dòng)填充
項(xiàng)目中經(jīng)常會(huì)遇到一些數(shù)據(jù),每次都使用相同的方式填充代虾,例如記錄的創(chuàng)建時(shí)間进肯,更新時(shí)間等。
我們可以使用MyBatis Plus的自動(dòng)填充功能棉磨,完成這些字段的賦值工作:
(1)數(shù)據(jù)庫表中添加自動(dòng)填充字段
在User表中添加datetime類型的新的字段?create_time江掩、update_time
(2)實(shí)體上添加注解
@TableField(fill =FieldFill.INSERT)
private Date createTime;
@TableField(fill =FieldFill.INSERT_UPDATE)
private Date updateTime;
(3)實(shí)現(xiàn)元對(duì)象處理器接口
注意:不要忘記添加 @Component 注解
package com.example.mpdemo.handler;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
????@Override
? ? public void insertFill(MetaObject metaObject) {
????????this.setFieldValByName("createTime",new Date(), metaObject);
????????this.setFieldValByName("updateTime",new Date(), metaObject);
????}
????@Override
? ? public void updateFill(MetaObject metaObject) {
????????this.setFieldValByName("updateTime",new Date(), metaObject);
????}
}
3、樂觀鎖
主要適用場景:當(dāng)要更新一條記錄的時(shí)候乘瓤,希望這條記錄沒有被別人更新环形,也就是說實(shí)現(xiàn)線程安全的數(shù)據(jù)更新
樂觀鎖實(shí)現(xiàn)方式:
????取出記錄時(shí),獲取當(dāng)前version
????更新時(shí)衙傀,帶上這個(gè)version
????執(zhí)行更新時(shí)抬吟, set version = newVersion where version = oldVersion
????如果version不對(duì),就更新失敗
(1)數(shù)據(jù)庫中添加version字段
ALTER TABLE `user` ADD COLUMN version INT;
(2)實(shí)體類添加version字段
并添加 @Version 注解
@Version
@TableField(fill =FieldFill.INSERT)
private Integer version;
(3)元對(duì)象處理器接口添加version的insert默認(rèn)值
package com.example.mpdemo.handler;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
????@Override
? ? public void insertFill(MetaObject metaObject) {
????????this.setFieldValByName("createTime",new Date(), metaObject);
????????this.setFieldValByName("updateTime",new Date(), metaObject);
????????this.setFieldValByName("version",1,metaObject);
????}
????@Override
? ? public void updateFill(MetaObject metaObject) {
????????this.setFieldValByName("updateTime",new Date(), metaObject);
????}
}
特別說明:
????支持的數(shù)據(jù)類型只有 int,Integer,long,Long,Date,Timestamp,LocalDateTime
????整數(shù)類型下?newVersion = oldVersion + 1
????newVersion?會(huì)回寫到?entity?中
????僅支持?updateById(id)?與?update(entity, wrapper)?方法
????在?update(entity, wrapper)?方法下,?wrapper?不能復(fù)用!!!
(4)在 MybatisPlusConfig 中注冊 Bean
創(chuàng)建配置類
package com.example.mpdemo.config;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration //配置類
@MapperScan("com.example.mpdemo.mapper")? //將啟動(dòng)類中的刪除在配置類中編寫
public class MpConfig {
????/**
? ? * 樂觀鎖插件
? ? */
? ? @Bean
? ? public OptimisticLockerInterceptor optimisticLockerInterceptor() {
????????return new OptimisticLockerInterceptor();
????}
}
(5)測試樂觀鎖可以修改成功
測試后分析打印的sql語句统抬,將version的數(shù)值進(jìn)行了加1操作
//測試樂觀鎖
@Test
void testOptimisticLocker(){
????//根據(jù)id查詢數(shù)據(jù)
? ? User user =userMapper.selectById(1277422156430458882L);
????//修改數(shù)據(jù)
? ? user.setName("Helen Yao");
????user.setEmail("helen@qq.com");
????//執(zhí)行更新
? ? userMapper.updateById(user);
}
三火本、select
1、根據(jù)id查詢記錄
Useruser=userMapper.selectById(1L);
2聪建、通過多個(gè)id批量查詢
完成了動(dòng)態(tài)sql的foreach的功能
//多個(gè)id批量查詢
@Test
void testSelectDemo1(){
????List<User> users =userMapper.selectBatchIds(Arrays.asList(1L,2L,3L));
????System.out.println(users);
}
3钙畔、簡單的條件查詢
通過map封裝查詢條件
@Test
public void testSelectByMap(){
????HashMapmap =new HashMap<>();
????map.put("name","Helen Yao");
????map.put("age",60);
????List users =userMapper.selectByMap(map);
????users.forEach(System.out::println);
}
注意:map中的key對(duì)應(yīng)的是數(shù)據(jù)庫中的列名。例如數(shù)據(jù)庫user_id金麸,實(shí)體類是userId擎析,這時(shí)map的key需要填寫user_id
4、分頁
MyBatis Plus自帶分頁插件挥下,只要簡單的配置即可實(shí)現(xiàn)分頁功能
(1)創(chuàng)建配置類
此時(shí)可以刪除主類中的?@MapperScan?掃描注解
/**
* 分頁插件
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
????????return new PaginationInterceptor();
}
(2)測試selectPage分頁
測試:最終通過page對(duì)象獲取相關(guān)數(shù)據(jù)
//分頁查詢
@Test
void testPage(){
????//1 創(chuàng)建page對(duì)象
? ? //傳入兩個(gè)參數(shù):當(dāng)前頁和每頁顯示記錄數(shù)
? ? Pagepage =new Page<>(1,3);
????//調(diào)用mp分頁查詢的方法
? ? //調(diào)用mp分頁查詢過程中叔锐,底層封裝
? ? //把分頁所有數(shù)據(jù)封裝到page對(duì)象里面
? ? userMapper.selectPage(page,null);
????//通過page對(duì)象獲取分頁數(shù)據(jù)
? ? System.out.println(page.getCurrent());
????System.out.println(pa ge.getPages());//每頁數(shù)據(jù)list集合
? ? System.out.println(page.getSize());
????System.out.println(page.getTotal());
????System.out.println(page.hasNext());
????System.out.println(page.hasPrevious());
}
控制臺(tái)sql語句打优才簟:SELECT id,name,age,email,create_time,update_time,version FROM user LIMIT 0,3
四见秽、delete
1愉烙、根據(jù)id刪除記錄
//刪除操作 (物理刪除)
@Test
void testDeleteById(){
????int result =userMapper.deleteById(1L);
????System.out.println(result);
}
2、批量刪除
//批量刪除
@Test
public void testDeleteBatchIds() {
????int result =userMapper.deleteBatchIds(Arrays.asList(8,9,10));
????System.out.println(result);
}
3解取、簡單的條件查詢刪除
@Test
public void testDeleteByMap() {
????HashMap<String, Object>? map =new HashMap<>();
????map.put("name","lucy");
????map.put("age",120);
????int result =userMapper.deleteByMap(map);
????System.out.println(result);
}
4步责、邏輯刪除
物理刪除:真實(shí)刪除,將對(duì)應(yīng)數(shù)據(jù)從數(shù)據(jù)庫中刪除禀苦,之后查詢不到此條被刪除數(shù)據(jù)
邏輯刪除:假刪除蔓肯,將對(duì)應(yīng)數(shù)據(jù)中代表是否被刪除字段狀態(tài)修改為“被刪除狀態(tài)”,之后在數(shù)據(jù)庫中仍舊能看到此條數(shù)據(jù)記錄
(1)數(shù)據(jù)庫中添加 deleted字段
ALTER TABLE `user` ADD COLUMN `deleted` boolean
(2)實(shí)體類添加deleted字段
并加上 @TableLogic 注解 和 @TableField(fill = FieldFill.INSERT) 注解
@TableLogic //邏輯刪除的注解
@TableField(fill =FieldFill.INSERT)
private Integer deleted;
(3)元對(duì)象處理器接口添加deleted的insert默認(rèn)值
this.setFieldValByName("deleted",0,metaObject);
(4)application.properties 加入配置
此為默認(rèn)值振乏,如果你的默認(rèn)值和mp默認(rèn)的一樣,該配置可無
#mybatis-plus.global-config.db-config.logic-delete-value=1
#mybatis-plus.global-config.db-config.logic-not-delete-value=0
(5)在 MybatisPlusConfig 中注冊 Bean
@Bean
public ISqlInjector sqlInjector() {
????return new LogicSqlInjector();
}
(6)測試邏輯刪除
????測試后發(fā)現(xiàn)蔗包,數(shù)據(jù)并沒有被刪除,deleted字段的值由0變成了1
????測試后分析打印的sql語句慧邮,是一條update
注意:被刪除數(shù)據(jù)的deleted 字段的值必須是 0调限,才能被選取出來執(zhí)行邏輯刪除的操作
/**
* 測試 邏輯刪除
*/
@Test
public void testLogicDelete() {
????????int result =userMapper.deleteById(1L);
????????System.out.println(result);
}
(7)測試邏輯刪除后的查詢
MyBatis Plus中查詢操作也會(huì)自動(dòng)添加邏輯刪除字段的判斷
/**
* 測試 邏輯刪除后的查詢:
* 不包括被邏輯刪除的記錄
*/
@Test
public void testLogicDeleteSelect() {
????????User user =new User();
????????Listusers =userMapper.selectList(null);
????????users.forEach(System.out::println);
}
測試后分析打印的sql語句,包含 WHERE deleted=0?
SELECT id,name,age,email,create_time,update_time,version,deleted FROM user WHERE deleted=0
五误澳、性能分析
性能分析攔截器耻矮,用于輸出每條 SQL 語句及其執(zhí)行時(shí)間
SQL 性能執(zhí)行分析,開發(fā)環(huán)境使用,超過指定時(shí)間忆谓,停止運(yùn)行裆装。有助于發(fā)現(xiàn)問題
1、配置插件
(1)參數(shù)說明
參數(shù):maxTime: SQL 執(zhí)行最大時(shí)長倡缠,超過自動(dòng)停止運(yùn)行哨免,有助于發(fā)現(xiàn)問題。
參數(shù):format: SQL是否格式化昙沦,默認(rèn)false琢唾。
(2)在 MybatisPlusConfig 中配置
/**
* SQL 執(zhí)行性能分析插件
* 開發(fā)環(huán)境使用,線上不推薦桅滋。 maxTime 指的是 sql 最大執(zhí)行時(shí)長
*
*三種環(huán)境
* dev:開發(fā)環(huán)境
* test:測試環(huán)境
* prod:生產(chǎn)環(huán)境
*/
@Bean
@Profile({"dev","test"})? // 設(shè)置 dev test 環(huán)境開啟
public PerformanceInterceptor performanceInterceptor() {
????PerformanceInterceptor performanceInterceptor =new PerformanceInterceptor();
????performanceInterceptor.setMaxTime(100);//ms慧耍,超過此處設(shè)置的ms則sql不執(zhí)行
? ? performanceInterceptor.setFormat(true);
????return performanceInterceptor;
}
(3)Spring Boot 中設(shè)置dev環(huán)境
#環(huán)境設(shè)置:dev、test丐谋、prod
spring.profiles.active=dev
可以針對(duì)各環(huán)境新建不同的配置文件application-dev.properties芍碧、application-test.properties、application-prod.properties
也可以自定義環(huán)境名稱:如test1号俐、test2
2泌豆、測試
六、其它
如果想進(jìn)行復(fù)雜條件查詢吏饿,那么需要使用條件構(gòu)造器 Wapper踪危,涉及到如下方法
1蔬浙、delete
2、selectOne
3贞远、selectCount
4畴博、selectList
5、selectMaps
6蓝仲、selectObjs
7俱病、update
04-MyBatisPlus條件構(gòu)造器
一、wapper介紹?
Wrapper : 條件構(gòu)造抽象類袱结,最頂端父類
? ? AbstractWrapper : 用于查詢條件封裝亮隙,生成 sql 的 where 條件
? ? ? ? QueryWrapper : Entity 對(duì)象封裝操作類,不是用lambda語法
? ? ? ? UpdateWrapper : Update 條件封裝垢夹,用于Entity對(duì)象更新操作
? ? AbstractLambdaWrapper : Lambda 語法使用 Wrapper統(tǒng)一處理解析 lambda 獲取 column溢吻。
? ? ? ? LambdaQueryWrapper :看名稱也能明白就是用于Lambda語法使用的查詢Wrapper
? ? ? ? LambdaUpdateWrapper : Lambda 更新封裝Wrapper
二、AbstractWrapper
注意:以下條件構(gòu)造器的方法入?yún)⒅械?column?均表示數(shù)據(jù)庫字段
1果元、ge促王、gt、le噪漾、lt硼砰、isNull、isNotNull
//創(chuàng)建QueryWrapper對(duì)象
QueryWrapper<User> wrapper =new QueryWrapper<>();
//通過QueryWrapper設(shè)置條件
//大于等于ge欣硼、大于gt题翰、le、lt
//查詢age>=30記錄
//第一個(gè)參數(shù)字段名稱诈胜,第二個(gè)參數(shù)設(shè)置值
wrapper.ge("age",60);
List<User> users =userMapper.selectList(wrapper);
System.out.println(users);
2豹障、eq、ne
注意:seletOne返回的是一條實(shí)體記錄焦匈,當(dāng)出現(xiàn)多條時(shí)會(huì)報(bào)錯(cuò)
//eq血公、ne
//wrapper.eq("name","東方");
wrapper.ne("name","東方");
List<User> users =userMapper.selectList(wrapper);
System.out.println(users);
3、between缓熟、notBetween
包含大小邊界
wrapper.between("age",20,60);
List<User> users =userMapper.selectList(wrapper);
System.out.println(users);
4累魔、allEq
//allEq
Map<String,Object> map =new HashMap<>();
map.put("id",2);
map.put("name","Jack");
wrapper.allEq(map);
List<User> users =userMapper.selectList(wrapper);
System.out.println(users);
5、like够滑、notLike垦写、likeLeft、likeRight
selectMaps返回Map集合列表
wrapper.like("name","T");
List users =userMapper.selectList(wrapper);
System.out.println(users);
6彰触、in梯投、notIn、inSql、notinSql分蓖、exists尔艇、notExists
in、notIn:
notIn("age", 1, 2, 3)--->age not in (1,2,3)
inSql么鹤、notinSql:可以實(shí)現(xiàn)子查詢
例:?wrapper.inSql("id","1,2,3,4");--->wrapper.in("id",2,3,4,5);
例:?inSql("id", "select id from table where id < 3")--->id in (select id from table where id < 3)
@Test
publicvoidtestSelectObjs() {
????????QueryWrapper<User> queryWrapper=newQueryWrapper<>();
????????//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,version,deleted FROM user WHERE deleted=0 AND id IN (select id from user where id < 3)
7终娃、or、and
注意:這里使用的是?UpdateWrapper?
不調(diào)用or則默認(rèn)為使用?and?連
@Test
void testUpdate1(){
????User user =new User();
????user.setAge(99);
????user.setName("Andy");
????UpdateWrapperuserUpdateWrapper =new UpdateWrapper<>();
????userUpdateWrapper.like("name","h")
????????.or()
????????.between("age",20,40);
????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午磁、嵌套o(hù)r尝抖、嵌套and
這里使用了lambda表達(dá)式,or中的表達(dá)式最后翻譯成sql時(shí)會(huì)被加上圓括號(hào)
userUpdateWrapper
????.like("name","h")
????.or(i->i.eq("name","李白").ne("age",20));
UPDATE user SET name=?, age=?, update_time=??
WHERE deleted=0 AND name LIKE ??
OR ( name = ? AND age <> ? )?
9迅皇、orderBy、orderByDesc衙熔、orderByAsc
queryWrapper.orderByDesc("id");
10登颓、last
直接拼接到 sql 的最后
注意:只能調(diào)用一次,多次調(diào)用以最后一次為準(zhǔn) 有sql注入的風(fēng)險(xiǎn),請謹(jǐn)慎使用
queryWrapper.last("limit 1");
SELECT id,name,age,email,create_time,update_time,deleted,version?
FROM user WHERE deleted=0?limit 1?
11、指定要查詢的列
queryWrapper.select("id","name","age");
SELECT id,name,age FROM user WHERE deleted=0?
12红氯、set框咙、setSql
最終的sql會(huì)合并 user.setAge(),以及 userUpdateWrapper.set() ?和 setSql() 中 的字段
userUpdateWrapper
????.like("name","h")
????.set("name","老李頭")//除了可以查詢還可以使用set設(shè)置修改的字段
????.setSql(" email = '123@qq.com'");//可以有子查詢
UPDATE user SET age=?, update_time=?, name=?, email = '123@qq.com' WHERE deleted=0 AND name LIKE ??