千家信息网

Mybatis Plus使用queryWrapper怎么实现复杂查询

发表于:2025-02-20 作者:千家信息网编辑
千家信息网最后更新 2025年02月20日,这篇文章主要讲解了"Mybatis Plus使用queryWrapper怎么实现复杂查询",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Mybatis
千家信息网最后更新 2025年02月20日Mybatis Plus使用queryWrapper怎么实现复杂查询

这篇文章主要讲解了"Mybatis Plus使用queryWrapper怎么实现复杂查询",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Mybatis Plus使用queryWrapper怎么实现复杂查询"吧!

使用queryWrapper实现复杂查询

//    mp实现负责查询操作    @Test    public void testSelectQuery(){        //1,创建QueryWrapper对象        QueryWrapper wrapper = new QueryWrapper<>();//        2,通过QueryWrapper设置条件//        ge大于等于  gt大于  le小于等于 lt   eq等于  ne不等于  between  like模糊查询//        orderByDesc   last拼接//        查询age>=30的记录 第一个参数 字段的名字,第二个参数设置值        wrapper.ge("age",30);        List users = userMapper.selectList(wrapper);        System.out.println(users);//        eq        wrapper.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-30        wrapper.between("age",20,30);        List users3 = userMapper.selectList(wrapper);        System.out.println(users3);//        like        wrapper.like("Tian","T");        List users4 = userMapper.selectList(wrapper);        System.out.println(users4);//        orderByDesc        wrapper.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");    }

自定义的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 = "dq_user")public class DqUser extends DqStatusDispose implements Serializable {    private static final long serialVersionUID = 1L;    /** 用户ID */    /**     * 主键使用TableId注解,否则MybatisPlus默认使用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;    /** 手机号码 */    @Size(min = 0, max = 11, message = "手机号码长度不能超过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;    /** 帐号状态(0正常 1停用) */    @TableField(value = "status")    private String status;    /** 删除标志(0代表存在 1代表删除,暂时没打算用) */    @TableField(value = "delFlag")    private String delFlag;    /** 最后登录IP */    @TableField(value = "loginIp")    private String loginIp;    /** 最后登录时间 */    @TableField(value = "loginDate")    private Date loginDate;    /** 用户角色ID */    @TableField(value = "role")    private String role;    /** 个性签名 **/    @TableField(value = "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 = 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来查,那可以设定注解有优先等级来解决。

感谢各位的阅读,以上就是"Mybatis Plus使用queryWrapper怎么实现复杂查询"的内容了,经过本文的学习后,相信大家对Mybatis Plus使用queryWrapper怎么实现复杂查询这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

0