MybatisPlus使用queryWrapper如何實(shí)現(xiàn)復(fù)雜查詢
使用queryWrapper實(shí)現(xiàn)復(fù)雜查詢
// mp實(shí)現(xiàn)負(fù)責(zé)查詢操作
@Test
public void testSelectQuery(){
//1,創(chuàng)建QueryWrapper對象
QueryWrapper<User> wrapper = new QueryWrapper<>();
// 2,通過QueryWrapper設(shè)置條件
// ge大于等于 gt大于 le小于等于 lt eq等于 ne不等于 between like模糊查詢
// orderByDesc last拼接
// 查詢age>=30的記錄 第一個參數(shù) 字段的名字,第二個參數(shù)設(shè)置值
wrapper.ge("age",30);
List<User> users = userMapper.selectList(wrapper);
System.out.println(users);
// eq
wrapper.eq("name","Tian");
List<User> users1 = userMapper.selectList(wrapper);
System.out.println(users1);
wrapper.ne("name","Tian");
List<User> users2 = userMapper.selectList(wrapper);
System.out.println(users2);
// between
// 查詢年齡20-30
wrapper.between("age",20,30);
List<User> users3 = userMapper.selectList(wrapper);
System.out.println(users3);
// like
wrapper.like("Tian","T");
List<User> users4 = userMapper.selectList(wrapper);
System.out.println(users4);
// orderByDesc
wrapper.orderByAsc("age");
List<User> users5 = userMapper.selectList(wrapper);
System.out.println(users5);
// last 拼接
wrapper.last("limit 1");
List<User> users6 = userMapper.selectList(wrapper);
System.out.println(users6);
// 指定要查詢的列
QueryWrapper<User> select = wrapper.select("id", "name");
}
自定義的queryWrapper實(shí)現(xiàn)查詢
想要用QueryMapper,而不用xml,所以為了實(shí)現(xiàn)若依那樣的,自己重寫了QueryMapper
原有的mybatis的查詢方法,例如查詢一個用戶,那么查詢方法就傳一個用戶,然后在mapper.xml中對用戶的各項(xiàng)屬性進(jìn)行判斷,然后再拼接相應(yīng)的sql語句,就可以一次性實(shí)現(xiàn)查詢。雖然有mybatisX代碼生成器,或者自己寫代碼生成器,但是多個表的話感覺還是有點(diǎn)不好用。所以,自己使用反射寫了一個QueryWrapper的myAllEq方法,可以實(shí)現(xiàn)傳入一個實(shí)體類,直接實(shí)現(xiàn)全部屬性查詢
聲明提要
package com.maoyan.quickdevelop.common.core.domain;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.maoyan.quickdevelop.common.core.domain.dqabstract.DqStatusDispose;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.Email;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.util.Date;
/**
* @author 貓顏
* @date 2021/5/27 21:28
* 用戶實(shí)體類
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName(value = "dq_user")
public class DqUser extends DqStatusDispose implements Serializable {
private static final long serialVersionUID = 1L;
/** 用戶ID */
/**
* 主鍵使用TableId注解,否則MybatisPlus默認(rèn)使用id來查詢
*/
@TableId(value = "user_id")
private Long userId;
/** 用戶賬號 */
@TableField(value = "user_name")
private String userName;
/** 用戶昵稱 */
@TableField(value = "nick_name")
private String nickName;
/** 用戶郵箱 */
@Email(message = "郵箱格式不正確")
@TableField(value = "email")
private String email;
/** 手機(jī)號碼 */
@Size(min = 0, max = 11, message = "手機(jī)號碼長度不能超過11個字符")
@TableField(value = "phone_number")
private String phonenumber;
/** 用戶性別 0=男,1=女,2=未知*/
@TableField(value = "sex")
private String sex;
/** 用戶頭像 */
@TableField(value = "avatar")
private String avatar;
/** 密碼 */
@TableField(value = "password")
private String password;
/** 帳號狀態(tài)(0正常 1停用) */
@TableField(value = "status")
private String status;
/** 刪除標(biāo)志(0代表存在 1代表刪除,暫時沒打算用) */
@TableField(value = "delFlag")
private String delFlag;
/** 最后登錄IP */
@TableField(value = "loginIp")
private String loginIp;
/** 最后登錄時間 */
@TableField(value = "loginDate")
private Date loginDate;
/** 用戶角色I(xiàn)D */
@TableField(value = "role")
private String role;
/** 個性簽名 **/
@TableField(value = "signature")
private String signature;
/** 創(chuàng)建時間 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/** 更新時間 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}
- 我的用戶實(shí)體類中,使用lombak,里面有serialVersionUID。
- 使用的是注解來映射數(shù)據(jù)庫字段名
核心代碼
/**
* TODO 自定義遍歷查詢方法
*
* @param object
* @return com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<T>
* @author 貓顏
* @date 下午9:20
*/
public QueryWrapper<T> myAllEq(T object) throws IllegalAccessException,
NoSuchMethodException,
InvocationTargetException {
String getMethodName = "";
Field field = null;
Class<?> aClass = object.getClass();
Field[] declaredFields = aClass.getDeclaredFields();
// QueryWrapper<T> queryWrapper = new QueryWrapper<>();
//第一個為serialVersionUID(舍去) i為1 繞過
//獲取object的所有字段
for (int i = 1; i < declaredFields.length; i++) {
field = declaredFields[i];
//類中的成員變量為private,故必須進(jìn)行此操
field.setAccessible(true);
// 不能直接獲取到值,可以通過構(gòu)造get方法,或者調(diào)用類的get方法來獲取值
// 通過StringUtils的containsIgnoreCase方法來獲取方法名稱
// 通過上面那種方法,有循環(huán)嵌套,性能需要優(yōu)化
// 所以采取拼接get方法名
/**
*
* @author 貓顏
* @date //獲取屬性名稱
* for (Field field:
* declaredFields) {
* System.out.println(field.getName());
* methodNameFirst = field.getName().substring(0,1).toUpperCase();
* methodName = field.getName();
* methodName = "get"+methodNameFirst+methodName.substring(1);
* System.out.println("方法名稱為:"+methodName);
*
* // 優(yōu)化
* System.out.println("優(yōu)化:"+"get"+field.getName().substring(0,1).toUpperCase()+field.getName().substring(1));
* } 下午5:18
* @param object
* @return com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<T>
*/
//獲取get方法名稱
getMethodName = "get" + declaredFields[i].getName().substring(0, 1).toUpperCase() + declaredFields[i].getName().substring(1);
System.out.println(getMethodName);
// 執(zhí)行g(shù)et方法獲取屬性值
//執(zhí)行方法
Method method = aClass.getMethod(getMethodName, null);
Object getValue = method.invoke(object, null);
//System.out.println("輸出為:"+invoke);
// System.out.println("優(yōu)化:"+"get"+declaredFields[i].getName().substring(0,1).toUpperCase()+declaredFields[i].getName().substring(1));
// 如果值不為空,則添加到eq中
if (getValue != null) {
//映射關(guān)系
// return super.eq(,field.get(object));
//獲取其注解的值
// 后面可以采用查詢方法注釋來解決,不同的查詢所需的問題
System.out.println("表的值:" + field.getAnnotation(TableField.class).value());
System.out.println("get獲取值:" + getValue.toString());
MyQueryWrapper.this.eq(field.getAnnotation(TableField.class).value(), getValue.toString());
}
}
return MyQueryWrapper.this;
}
可以使用
//獲取所有的方法名稱
//但是順序是與類中的一樣,所以可以構(gòu)建get方法
//屬性名稱第一個大寫,然后加上get就是,get方法名稱
Method[] methods = aClass.getMethods();
for (Method method:
methods) {
System.out.println(method.getName());
if (StringUtils.containsIgnoreCase(method.getName(),"get")&&
StringUtils.containsIgnoreCase(method.getName(),"username")){
System.out.println("值為:"+method.getName());
}
}
StringUtils.containsIgnoreCase方法來獲取get方法,但是會造成循環(huán)嵌套,對性能有一定的影響。
所以,我采用拼接get方法名稱的方法,減少無用循環(huán)帶來的影響。
- 根據(jù)上面的要點(diǎn)提示,for是從1開始,因?yàn)榈谝粋€是serialVersionUID,所以為了跳過他。從1開始
- 對于xml中,可以使用like等查詢,我這個是適用于=查詢,所以后續(xù)會通過在用戶類的屬性上加上自定義注解,來判斷這個字段所用的查詢方式,對于一個字段,有些地方想用=來查,有些地方想用like來查,那可以設(shè)定注解有優(yōu)先等級來解決。
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java模擬有序鏈表數(shù)據(jù)結(jié)構(gòu)的示例
這篇文章主要介紹了Java模擬有序鏈表數(shù)據(jù)結(jié)構(gòu)的示例,包括一個反序的單鏈表結(jié)構(gòu)的例子,需要的朋友可以參考下2016-04-04
Mapstruct?@Mapper?@Mapping?使用小結(jié)
這篇文章主要介紹了Mapstruct?@Mapper?@Mapping使用小結(jié),他們用于各個對象實(shí)體間的相互轉(zhuǎn)換,例如數(shù)據(jù)庫底層實(shí)體轉(zhuǎn)為頁面對象,Model?轉(zhuǎn)為?DTO,?DTO?轉(zhuǎn)為其他中間對象,?VO?等等,相關(guān)轉(zhuǎn)換代碼為編譯時自動產(chǎn)生的新文件和代碼,需要的朋友可以參考下2023-09-09
Java中Object toString方法簡介_動力節(jié)點(diǎn)Java學(xué)院整理
Object類在Java里面是一個比較特殊的類,JAVA為了組織這個類組織得比較方便,它提供了一個最根上的類,相當(dāng)于所有的類都是從這個類繼承,這個類就叫Object。接下來通過本文給大家介紹Object toString方法,需要的的朋友參考下吧2017-05-05
SpringBoot WebSocket實(shí)時監(jiān)控異常的詳細(xì)流程
最近做了一個需求,消防的設(shè)備巡檢,如果巡檢發(fā)現(xiàn)異常,通過手機(jī)端提交,后臺的實(shí)時監(jiān)控頁面實(shí)時獲取到該設(shè)備的信息及位置,然后安排員工去處理。這篇文章主要介紹了SpringBoot WebSocket實(shí)時監(jiān)控異常的全過程,感興趣的朋友一起看看吧2021-10-10
Idea入門教程之一分鐘創(chuàng)建一個Java工程
idea作為Java開發(fā)最好用的編寫代碼軟件之一,首先進(jìn)行的就是工程的創(chuàng)建,這篇文章主要給大家介紹了關(guān)于Idea入門教程之一分鐘創(chuàng)建一個Java工程的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2024-07-07
詳解SpringSecurity如何實(shí)現(xiàn)前后端分離
這篇文章主要為大家介紹了詳解SpringSecurity如何實(shí)現(xiàn)前后端分離,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03
解決mybatis 執(zhí)行mapper的方法時報空指針問題
這篇文章主要介紹了解決mybatis 執(zhí)行mapper的方法時報空指針問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07

