MybatisPlus使用queryWrapper如何实现复杂查询

目录

  • 使用queryWrapper实现复杂查询
  • 自定义的queryWrapper实现查询
    • 声明提要
    • 核心代码

使用queryWrapper实现复杂查询
//mp实现负责查询操作@Testpublic void testSelectQuery(){//1,创建QueryWrapper对象QueryWrapper wrapper = new QueryWrapper<>(); //2,通过QueryWrapper设置条件//ge大于等于gt大于le小于等于 lteq等于ne不等于betweenlike模糊查询//orderByDesclast拼接//查询age>=30的记录 第一个参数 字段的名字,第二个参数设置值wrapper.ge("age",30); List users = userMapper.selectList(wrapper); System.out.println(users); //eqwrapper.eq("name","Tian"); List users1 = userMapper.selectList(wrapper); System.out.println(users1); wrapper.ne("name","Tian"); List users2 = userMapper.selectList(wrapper); System.out.println(users2); //between//查询年龄20-30wrapper.between("age",20,30); List users3 = userMapper.selectList(wrapper); System.out.println(users3); //likewrapper.like("Tian","T"); List users4 = userMapper.selectList(wrapper); System.out.println(users4); //orderByDescwrapper.orderByAsc("age"); List users5 = userMapper.selectList(wrapper); System.out.println(users5); //last 拼接wrapper.last("limit 1"); List users6 = userMapper.selectList(wrapper); System.out.println(users6); //指定要查询的列QueryWrapper select = wrapper.select("id", "name"); }

【MybatisPlus使用queryWrapper如何实现复杂查询】
自定义的queryWrapper实现查询 想要用QueryMapper,而不用xml,所以为了实现若依那样的,自己重写了QueryMapper
原有的mybatis的查询方法,例如查询一个用户,那么查询方法就传一个用户,然后在mapper.xml中对用户的各项属性进行判断,然后再拼接相应的sql语句,就可以一次性实现查询。虽然有mybatisX代码生成器,或者自己写代码生成器,但是多个表的话感觉还是有点不好用。所以,自己使用反射写了一个QueryWrapper的myAllEq方法,可以实现传入一个实体类,直接实现全部属性查询

声明提要
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 * 用户实体类 */@Data@NoArgsConstructor@AllArgsConstructor@TableName(value = "https://www.it610.com/article/dq_user")public class DqUser extends DqStatusDispose implements Serializable {private static final long serialVersionUID = 1L; /** 用户ID *//*** 主键使用TableId注解,否则MybatisPlus默认使用id来查询*/@TableId(value = "https://www.it610.com/article/user_id")private Long userId; /** 用户账号 */@TableField(value = "https://www.it610.com/article/user_name")private String userName; /** 用户昵称 */@TableField(value = "https://www.it610.com/article/nick_name")private String nickName; /** 用户邮箱 */@Email(message = "邮箱格式不正确")@TableField(value = "https://www.it610.com/article/email")private String email; /** 手机号码 */@Size(min = 0, max = 11, message = "手机号码长度不能超过11个字符")@TableField(value = "https://www.it610.com/article/phone_number")private String phonenumber; /** 用户性别 0=男,1=女,2=未知*/@TableField(value = "https://www.it610.com/article/sex")private String sex; /** 用户头像 */@TableField(value = "https://www.it610.com/article/avatar")private String avatar; /** 密码 */@TableField(value = "https://www.it610.com/article/password")private String password; /** 帐号状态(0正常 1停用) */@TableField(value = "https://www.it610.com/article/status")private String status; /** 删除标志(0代表存在 1代表删除,暂时没打算用) */@TableField(value = "https://www.it610.com/article/delFlag")private String delFlag; /** 最后登录IP */@TableField(value = "https://www.it610.com/article/loginIp")private String loginIp; /** 最后登录时间 */@TableField(value = "https://www.it610.com/article/loginDate")private Date loginDate; /** 用户角色ID */@TableField(value = "https://www.it610.com/article/role")private String role; /** 个性签名 **/@TableField(value = "https://www.it610.com/article/signature")private String signature; /** 创建时间 */@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private Date createTime; /** 更新时间 */@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private Date updateTime; }

  • 我的用户实体类中,使用lombak,里面有serialVersionUID。
  • 使用的是注解来映射数据库字段名

核心代码
/*** TODO 自定义遍历查询方法** @param object* @return com.baomidou.mybatisplus.core.conditions.query.QueryWrapper* @author 猫颜* @date 下午9:20*/public QueryWrapper myAllEq(T object) throws IllegalAccessException,NoSuchMethodException,InvocationTargetException {String getMethodName = ""; Field field = null; Class aClass = object.getClass(); Field[] declaredFields = aClass.getDeclaredFields(); //QueryWrapper queryWrapper = new QueryWrapper<>(); //第一个为serialVersionUID(舍去) i为1 绕过//获取object的所有字段for (int i = 1; i < declaredFields.length; i++) {field = declaredFields[i]; //类中的成员变量为private,故必须进行此操field.setAccessible(true); //不能直接获取到值,可以通过构造get方法,或者调用类的get方法来获取值//通过StringUtils的containsIgnoreCase方法来获取方法名称//通过上面那种方法,有循环嵌套,性能需要优化//所以采取拼接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); * * //优化 *System.out.println("优化:"+"get"+field.getName().substring(0,1).toUpperCase()+field.getName().substring(1)); *} 下午5:18 * @param object * @return com.baomidou.mybatisplus.core.conditions.query.QueryWrapper *///获取get方法名称getMethodName = "get" + declaredFields[i].getName().substring(0, 1).toUpperCase() + declaredFields[i].getName().substring(1); System.out.println(getMethodName); //执行get方法获取属性值//执行方法Method method = aClass.getMethod(getMethodName, null); Object getValue = https://www.it610.com/article/method.invoke(object, null); //System.out.println("输出为:"+invoke); //System.out.println("优化:"+"get"+declaredFields[i].getName().substring(0,1).toUpperCase()+declaredFields[i].getName().substring(1)); //如果值不为空,则添加到eq中if (getValue != null) {//映射关系//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; }

可以使用
//获取所有的方法名称//但是顺序是与类中的一样,所以可以构建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方法,但是会造成循环嵌套,对性能有一定的影响。
所以,我采用拼接get方法名称的方法,减少无用循环带来的影响。
  • 根据上面的要点提示,for是从1开始,因为第一个是serialVersionUID,所以为了跳过他。从1开始
  • 对于xml中,可以使用like等查询,我这个是适用于=查询,所以后续会通过在用户类的属性上加上自定义注解,来判断这个字段所用的查询方式,对于一个字段,有些地方想用=来查,有些地方想用like来查,那可以设定注解有优先等级来解决。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

    推荐阅读