day01-MyBatis入門

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 ??

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末痢甘,一起剝皮案震驚了整個(gè)濱河市喇嘱,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌塞栅,老刑警劉巖者铜,帶你破解...
    沈念sama閱讀 222,807評(píng)論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異放椰,居然都是意外死亡作烟,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門砾医,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拿撩,“玉大人,你說我怎么就攤上這事如蚜⊙购悖” “怎么了?”我有些...
    開封第一講書人閱讀 169,589評(píng)論 0 363
  • 文/不壞的土叔 我叫張陵错邦,是天一觀的道長探赫。 經(jīng)常有香客問我,道長兴猩,這世上最難降的妖魔是什么期吓? 我笑而不...
    開封第一講書人閱讀 60,188評(píng)論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上讨勤,老公的妹妹穿的比我還像新娘箭跳。我一直安慰自己,他們只是感情好潭千,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,185評(píng)論 6 398
  • 文/花漫 我一把揭開白布谱姓。 她就那樣靜靜地躺著,像睡著了一般刨晴。 火紅的嫁衣襯著肌膚如雪屉来。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,785評(píng)論 1 314
  • 那天狈癞,我揣著相機(jī)與錄音茄靠,去河邊找鬼。 笑死蝶桶,一個(gè)胖子當(dāng)著我的面吹牛慨绳,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播真竖,決...
    沈念sama閱讀 41,220評(píng)論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼脐雪,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了恢共?” 一聲冷哼從身側(cè)響起战秋,我...
    開封第一講書人閱讀 40,167評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎讨韭,沒想到半個(gè)月后脂信,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,698評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡拐袜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,767評(píng)論 3 343
  • 正文 我和宋清朗相戀三年吉嚣,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蹬铺。...
    茶點(diǎn)故事閱讀 40,912評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡尝哆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出甜攀,到底是詐尸還是另有隱情秋泄,我是刑警寧澤,帶...
    沈念sama閱讀 36,572評(píng)論 5 351
  • 正文 年R本政府宣布规阀,位于F島的核電站恒序,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏谁撼。R本人自食惡果不足惜歧胁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,254評(píng)論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧喊巍,春花似錦屠缭、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽殊橙。三九已至退盯,卻和暖如春婆赠,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背海洼。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評(píng)論 1 274
  • 我被黑心中介騙來泰國打工跨新, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人贰军。 一個(gè)月前我還...
    沈念sama閱讀 49,359評(píng)論 3 379
  • 正文 我出身青樓玻蝌,卻偏偏與公主長得像,于是被迫代替她去往敵國和親词疼。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,922評(píng)論 2 361