一.條件構造器
我們前面使用的MP功能主要是根據id進行操作的,并未涉及到復雜查詢。而根據id所進行的增刪改查操作在MP中都有直接的封裝。但是遇到復雜的查詢條件時,如何使用MP進行操作是我們要考慮的問題。因此MP為我們提供了條件構造器。

在BaseMapper接口中有很多Wrapper接口。這些Wrapper接口就是用來指定復雜查詢條件的。AbstractWrapper中實現了很多復雜條件的sql語句查詢。

eq:等于。ne:不等于。gt:大于。ge:大于等于。lt:小于。le:小于等于。like:模。也就是說復雜的where條件AbstractWrapper都能幫助我們構造。
我們關注下面的兩個子類UpdateWrapper和QueryWrapper。這兩個子類除了繼承AbstractWrapper,也可以構造復雜where語句外,在此基礎上擴展了相關的功能。如QueryWrapper用于查詢時,不僅可以用來構建復雜where語句,還可以進行select功能,指定要查詢的select字段(select column1, column2 ...?from ... where ...)。
?UpdateWrapper擴展了set部分,除了可以定義復雜where語句外,還可以設置set語句條件。可以使用setSql,在該方法里面使用字符串編寫set條件,直接拼入sql語句中。

這個在特殊場景下會用到,但比較少見。
綜上,UpdateWrapper和QueryWrapper就是在AbstractWrapper的基礎上做了拓展。
除了這些還有對應的Lambda,這些LambdaUpdateWrapper和LambdaQueryWrapper功能上與上面的一樣,只是使用了Lambda表達式。
二.案例演示
1.QueryWrapper


@Testvoid testQueryByQueryWrapper() {QueryWrapper<User> queryWrapper = new QueryWrapper<User>().select("id","username","info","balance").like("username","o").ge("balance",1000);userMapper.selectList(queryWrapper);}// 將Jack的余額設置為2000@Testvoid testUpdateByQueryWrapper() {// 1.要更新的數據User user = new User();user.setBalance(2000);// 2.更新的條件QueryWrapper<User> queryWrapper = new QueryWrapper<User>().eq("username","Jack");// 3.執行更新userMapper.update(user,queryWrapper);}
QueryWrapper可以支持鏈式編程,在第一個演示案例中我們除了定義復雜的查詢語句外,還使用QueryWrapper來指定要查詢的字段。通過其中的select方法來指定。
在第二個演示案例中我們要指定更新的數據,即創建一個User對象并將余額設置為2000。然后使用QueryWrapper來定義復雜的查詢語句并執行更新。
因為是查詢語句,且查詢出來的是一個列表,因此使用selectList進行查詢。并將QueryWrapper對象傳入。
2.UpdateWrapper

void testUpdateQuery() {List<Long> ids = List.of(1L,2L,4L);// 1.構造Wrapper對象UpdateWrapper<User> updateWrapper = new UpdateWrapper<User>().setSql("balance = balance - 200").in("id",ids);// 2.執行更新操作。由于這次每個用戶余額均不相同,因此無法創建對象來指定余額值,且每個用戶余額不同,因此要使用updateWrapper的setSql動態拼接sql語句,且在updateWrapper中指定要操作的數據類型userMapper.update(null,updateWrapper);}
這個情況比較特殊,由于這次每個用戶余額均不相同,因此無法創建對象來指定余額值,且每個用戶余額不同,因此要使用updateWrapper的setSql動態拼接sql語句,且在updateWrapper中指定要操作的數據類型。
sql語句要使用in,因此要構建一個集合來封裝id。
在這里由于是根據不同User動態更新,因此使用setSql指定更新條件為balance = balance - 200。
三.Lambda表達式
我們上邊的代碼在指定字段時都是硬編碼,即直接將字段名寫死。這樣不好因此我們要使用軟編碼。這就要使用Lambda表達式。
// 查詢出名字帶o的,存款大于等于1000元的id,username,info,balance字段@Testvoid testLambdaQueryByQueryWrapper() {LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<User>().select(User::getId,User::getUsername,User::getInfo,User::getBalance).like(User::getUsername,"o").ge(User::getBalance,1000);userMapper.selectList(queryWrapper);}// 將Jack的余額設置為2000@Testvoid testUpdateByLambdaQueryWrapper() {// 1.要更新的數據User user = new User();user.setBalance(2000);// 2.更新的條件LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<User>().eq(User::getBalance,"Jack");// 3.執行更新userMapper.update(user,queryWrapper);}// 將用戶id為1,2,4的用戶余額減200@Testvoid testLambdaUpdateQuery() {List<Long> ids = List.of(1L,2L,4L);// 1.構造Wrapper對象LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<User>().setSql("balance = balance - 200").in(User::getId,ids);// 2.執行更新操作。由于這次每個用戶余額均不相同,因此無法創建對象來指定余額值,且每個用戶余額不同,因此要使用updateWrapper的setSql動態拼接sql語句,且在updateWrapper中指定要操作的數據類型userMapper.update(null,updateWrapper);}
使用Lambda表達式,將字段換為查詢對象::get方法,利用反射來獲取字段。
