目錄
1.wrapper介紹
2.QueryWrapper
2.1 例1:組轉查詢條件
Compare
Nested
Join
Func
?2.2 例2:組裝排序條件
?2.3 例3:組裝刪除條件
?2.4 例4:條件的優先級
2.5 例5:組裝select子句
?2.6 例6:實現子查詢
3.UpdateWrapper
4.Condition
4.1 思路一
4.2 思路二:
5.LambdaQueryWrapper?
6.LambdaUpdateWrapper
1.wrapper介紹
Wrapper?: 條件構造抽象類,最頂端父類
???????AbstractWrapper?: 用于查詢條件封裝,生成 sql?的 where?條件
??? ????????QueryWrapper?: 查詢條件封裝
??? ????????UpdateWrapper?:?Update?條件封裝
??? ????????AbstractLambdaWrapper?: 使用Lambda?語法
?? ?????????????????LambdaQueryWrapper?:用于Lambda語法使用的查詢Wrapper
?? ? ????????????????LambdaUpdateWrapper?:?Lambda?更新封裝Wrapper
ctrl+h
2.QueryWrapper
2.1 例1:組轉查詢條件
/**** 按查詢條件組裝*/
@Test
public void test01(){QueryWrapper<People> queryWrapper=new QueryWrapper<>();//SELECT id,username AS name,age,email,is_deleted// FROM t_people// WHERE is_deleted=0 AND (username LIKE ? AND age BETWEEN ? AND ? AND email IS NOT NULL)queryWrapper.like("username","a").between("age",20,30).isNotNull("email");List<People> list=peopleMapper.selectList(queryWrapper);list.forEach(System.out::println);
}
QueryWrapper繼承AbstractWrapper,我們點擊AbstractWrapper進去看看。?
????????我們能看到AbstrackWrapper實現了這四個接口。
Compare
- 作用:用于構建比較條件,比如等于(
eq
)、不等于(ne
)、大于(gt
)、小于(lt
)等條件。在構建 SQL 查詢條件時,可用來描述實體屬性和具體值之間的比較關系 。
Nested
- 作用:用于構建嵌套查詢條件,當需要在查詢條件中添加括號包裹的子條件時會用到。可以讓查詢條件的邏輯結構更清晰,實現復雜的條件組合。
Join
- 作用:主要用于處理 SQL 的連接操作,比如內連接(
INNER JOIN
)、左連接(LEFT JOIN
)等。在多表查詢場景下,通過它來定義表與表之間的連接關系。
Func
- 作用:是一個函數式接口,通常用于封裝一些可復用的條件構建邏輯。可以將條件構建的代碼塊作為參數傳遞,方便代碼的復用和邏輯組織。
????????我們能夠看到,他們都是默認的方法, 繼承他的類可以直接使用這個方法,也可以進行重寫。同IService原碼
?2.2 例2:組裝排序條件
/**** 按排序組裝*/
@Test
public void test02(){QueryWrapper<People> queryWrapper=new QueryWrapper<>();queryWrapper.orderByDesc("age").orderByAsc("id");List<People> list=peopleMapper.selectList(queryWrapper);list.forEach(System.out::println);
}
?2.3 例3:組裝刪除條件
/**** 組裝刪除條件*/
@Test
public void test03(){QueryWrapper<People> queryWrapper=new QueryWrapper<>();queryWrapper.isNull("email");int result=peopleMapper.delete(queryWrapper);System.out.println("受影響的行數:"+result);
}
?2.4 例4:條件的優先級
/**** 優先級*/
@Test
public void test04(){QueryWrapper<People> queryWrapper=new QueryWrapper<>();//UPDATE t_people SET age=?, email=? // WHERE is_deleted=0 AND (username LIKE ? AND age > ? OR email IS NULL)queryWrapper.like("username", "a").gt("age", 20).or().isNull("email");People people=new People();people.setAge(18);people.setEmail("people@qcby.com");int result=peopleMapper.update(people,queryWrapper);System.out.println("受影響的行數:" + result);
}
?lambda表達式里的邏輯優先算法
/**** lambda表達式里的邏輯優先算法*/
@Test
public void test05(){QueryWrapper<People> queryWrapper=new QueryWrapper<>();//UPDATE t_people SET age=?, email=?// WHERE is_deleted=0 AND (username LIKE ? AND (age > ? OR email IS NULL))queryWrapper.like("username",'a').and(i ->i.gt("age",20).or().isNull("email"));People people=new People();people.setAge(18);people.setEmail("people@qcby.com");int result=peopleMapper.update(people,queryWrapper);System.out.println("受影響的行數:" + result);
}
2.5 例5:組裝select子句
/**** 組裝select語句*/
@Test
public void test06(){//查詢用戶信息的username和age字段//SELECT username,age FROM t_peopleQueryWrapper<People> queryWrapper=new QueryWrapper<>();queryWrapper.select("username","age");//selectMaps()返回Map集合列表,通常配合select()使用,// 避免People對象中沒有被查詢到的列值 為nullList<Map<String,Object>> maps=peopleMapper.selectMaps(queryWrapper);maps.forEach(System.out::println);
}
?2.6 例6:實現子查詢
/**** 實現子查詢*/
@Test
public void test07(){//SELECT id,username AS name,age,email,is_deleted FROM t_people // WHERE is_deleted=0 AND (id IN (select id from t_people where id<=3))QueryWrapper<People> queryWrapper=new QueryWrapper<>();queryWrapper.inSql("id","select id from t_people where id<=3");List<People> list=peopleMapper.selectList(queryWrapper);list.forEach(System.out::println);
}
3.UpdateWrapper
/**** UpdateWrapper*/
@Test
public void test08(){//將(年齡大于20或郵箱為null)并且用戶名中包含有a的用戶信息修改//組裝set子句以及修改條件UpdateWrapper<People> updateWrapper=new UpdateWrapper<>();//lambda表達式內的邏輯優先運算updateWrapper.set("age", 18).set("email", "user@qcby.com").like("username", "a").and(i -> i.gt("age", 20).or().isNull("email"));//UPDATE t_people SET age=?,email=?// WHERE is_deleted=0 AND// (username LIKE ? AND (age > ? OR email IS NULL))int result = peopleMapper.update(null, updateWrapper);System.out.println(result);
}
????????Lambda 表達式是 Java 8 引入的一個新特性,它可以讓你以更簡潔的方式表示一個匿名函數。
????????在這個例子中,i -> i.gt("age", 20).or().isNull("email")
?表示一個接受一個參數?i
,并對其進行一系列操作的函數。?
????????參數?i
?通常是 MyBatis-Plus 中的?QueryWrapper
?或者?UpdateWrapper
?對象,它們用于構建 SQL 查詢或者更新語句的條件部分。
4.Condition
????????在真正開發的過程中,組裝條件是常見的功能,而這些條件數據來源于用戶輸入,是可選的,因?此我們在組裝這些條件時,必須先判斷用戶是否選擇了這些條件,若選擇則需要組裝該條件,若?沒有選擇則一定不能組裝,以免影響SQL執行的結果
4.1 思路一
使用StringUtils的前提
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.12.0</version>
</dependency>
@Test
public void test09(){//定義查詢條件,有可能為null(用戶未輸入或未選擇)String username=null;Integer ageBegin = 10;Integer ageEnd = 24;QueryWrapper<People> queryWrapper = new QueryWrapper<>();//StringUtils.isNotBlank()判斷某字符串是否不為空且長度不為0且不由空白符(whitespace) 構成if(StringUtils.isNotBlank(username)){queryWrapper.like("username","a");}if(ageBegin != null){queryWrapper.ge("age", ageBegin);}if(ageEnd != null){queryWrapper.le("age", ageEnd);}//SELECT id,username AS name,age,email,is_deleted FROM t_user WHERE (age >= ? AND age <= ?)List<People> peoples = peopleMapper.selectList(queryWrapper);peoples.forEach(System.out::println);
}
4.2 思路二:
????????上面的實現方案沒有問題,但是代碼比較復雜,我們可以使用帶condition參數的重載方法構建查?詢條件,簡化代碼的編寫
@Test
public void test09UseCondition(){//定義查詢條件,有可能為null(用戶未輸入或未選擇)String username = null;Integer ageBegin = 10;Integer ageEnd = 24;QueryWrapper<People> queryWrapper = new QueryWrapper<>();
//StringUtils.isNotBlank()判斷某字符串是否不為空且長度不為0且不由空白符(whitespace) 構成queryWrapper.like(StringUtils.isNotBlank(username), "username", "a").ge(ageBegin != null, "age", ageBegin).le(ageEnd != null, "age", ageEnd);
//SELECT id,username AS name,age,email,is_deleted FROM t_user WHERE (age >= ? AND age <= ?)List<People> peoples = peopleMapper.selectList(queryWrapper);peoples.forEach(System.out::println);
}
5.LambdaQueryWrapper?
?
/**** LambdaQueryWrapper*/@Testpublic void test10() {
//定義查詢條件,有可能為null(用戶未輸入)String username = "a";Integer ageBegin = 10;Integer ageEnd = 24;LambdaQueryWrapper<People> queryWrapper = new LambdaQueryWrapper<>();
//避免使用字符串表示字段,防止運行時錯誤queryWrapper.like(StringUtils.isNotBlank(username), People::getName, username).ge(ageBegin != null, People::getAge, ageBegin).le(ageEnd != null, People::getAge, ageEnd);//SELECT id,username AS name,age,email,is_deleted FROM t_people // WHERE is_deleted=0 AND (username LIKE ? AND age >= ? AND age <= ?)List<People> peoples = peopleMapper.selectList(queryWrapper);peoples.forEach(System.out::println);}
????????在 Java 里,People::getAge
?屬于方法引用的一種形式。方法引用是 Java 8 引入的特性,它能夠讓你直接引用已有的方法,而無需顯式調用該方法。一般用于 Lambda 表達式能使用的地方,從而讓代碼更簡潔。?
6.LambdaUpdateWrapper
/**** 使用LambdaUpdateWrapper*/
@Test
public void test11(){LambdaUpdateWrapper<People> updateWrapper=new LambdaUpdateWrapper<>();//UPDATE t_people SET age=?, age=?,email=? WHERE is_deleted=0 AND (username LIKE ? AND (age < ? OR email IS NULL))updateWrapper.set(People::getAge,18).set(People::getEmail,"people@qcby.com").like(People::getName,"a").and(i ->i.lt(People::getAge,24).or().isNull(People::getEmail));//lambda 表達式內的邏輯優先運算People people=new People();int result=peopleMapper.update(people,updateWrapper);System.out.println("受影響的行數:" + result);
}
?
?