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

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

使用queryWrapper实现复杂查询

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

想要用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<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,故必须进行此操
            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<T>
 */
//获取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来查,那可以设定注解有优先等级来解决。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • MyBatis-Plus实现2种分页方法(QueryWrapper查询分页和SQL查询分页)

    目录 1 MyBatisPlusConfig 2 UserPagination 3 Mapper 3.1 UserMapper.java 3.2 UserMapper.xml 4 Service 4.1 UserService 4.2 UserServiceImpl 5 UserController 6 调试结果 6.1 QueryWrapper查询分页 6.2 SQL查询分页 1 MyBatisPlusConfig MyBatisPlus配置类. package com.config; imp

  • mybatis-plus QueryWrapper自定义查询条件的实现

    mybatis-plus框架功能很强大,把很多功能都集成了,比如自动生成代码结构,mybatis crud封装,分页,动态数据源等等,附上官网链接https://mp.baomidou.com/,github上有代码例子,国内小伙伴推荐码云https://gitee.com/baomidou/mybatis-plus.  但是,其中还是有些小坑,文档也没有涉及的很全面,碰到问题,百度或者发issue,能力强的还是直接看源码好,一切答案都在源码中. 版本推荐用3.1.0,3.1.1及以上版本有bu

  • lambdaQueryWrapper多条件嵌套查询方式

    目录 lambdaQueryWrapper多条件嵌套查询 表结构如下 下面是根据条件生成的SQL语句 LambdaQueryWrapper 常用条件 lambdaQueryWrapper多条件嵌套查询 需求:根据条件获取一段时期内按照年份和周存储的数据 表结构如下 userNetType moduleName cityName subjectCname subjectEname pv uv year week 1 1 江苏省 死神专题 sszt 100 70 2019 51 1 1 江苏省 海贼

  • QueryWrapper中查询的坑及解决

    目录 QueryWrapper中查询的坑 首先,先看代码示例 QueryWrapper的查询方法 QueryWrapper QueryWrapper中查询的坑 首先,先看代码示例 List<Entity> list = testService.list(                     new LambdaQueryWrapper<Entity>()                             .eq(ObjectUtils.isNotEmpty(req.get

  • mybatisplus where QueryWrapper加括号嵌套查询方式

    目录 where QueryWrapper加括号嵌套查询 mybatisplus查询语句加括号(.or(),.and()) where QueryWrapper加括号嵌套查询 之前的代码是这个样子的: QueryWrapper<RyxyMemberEntity> wrapper = new QueryWrapper<>();     wrapper.eq("phoneNumber", phone);     if (StringUtils.isEmpty(sce

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

    目录 使用queryWrapper实现复杂查询 自定义的queryWrapper实现查询 声明提要 核心代码 使用queryWrapper实现复杂查询 // mp实现负责查询操作 @Test public void testSelectQuery(){ //1,创建QueryWrapper对象 QueryWrapper<User> wrapper = new QueryWrapper<>(); // 2,通过QueryWrapper设置条件 // ge大于等于 gt大于 le小于等

  • MybatisPlus自定义Sql实现多表查询的示例

    前言 前段时间看同事的代码,发现他用Layui+MybatisPlus做分页查询做得很规整,认真看了下代码发现这种方式不仅适用于与Layui做分页查询,在任何时候需要多表联查的时候都可以用到.  以下以Layui分页查询作为参考,在实际应用中可以灵活使用. 分页查询VO对象 @Data @AllArgsConstructor @NoArgsConstructor public class LayuiData { private Integer code=0; private Long count

  • 如何利用反射生成 MyBatisPlus中QueryWrapper动态条件

    目录 1.问题 2.优化方案 1.问题 在MyBatisPlus中经常会用到如下所示的代码来构造查询条件: QueryWrapper<User> queryWrapper = new QueryWrapper<>(); if (userQuery.getId() != null) {     queryWrapper.eq("id", userQuery.getId()); } if (userQuery.getName() != null) {     que

  • Mybatis-Plus或PageHelper多表分页查询总条数不对问题的解决方法

    目录 前言 一.问题说明 1.引入依赖 2.Mybatis-Plus配置 3.创建mapper层 4.编写xxxMapper.xml文件 5.测试一(不传任何条件,只分页) 5.1.结果总结 5.2.结果分析 6.测试二(传两个表的条件) 6.1.测试结果 6.2.结果总结 6.3.结果分析 二.解决 1.没条件查询只分页 2.两个表都有条件 3.结果总结 4.结果分析 5.最终方案 5.1.坑 三.结束语 前言 项目老大说项目需要重构搜索功能,决定交给我这个比较闲的人! 嗯 ??? 因为以前的

  • SpringBoot整合MyBatis-Plus3.1教程详解

    一.说明 Mybatis-Plus是一个Mybatis框架的增强插件,根据官方描述,MP只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑.并且只需简单配置,即可快速进行 CRUD 操作,从而节省大量时间.代码生成,分页,性能分析等功能一应俱全,最新已经更新到了3.1.1版本了,3.X系列支持lambda语法,让我在写条件构造的时候少了很多的"魔法值",从代码结构上更简洁了. 二.项目环境 MyBatis-Plus版本: 3.1.0 SpringBoot版本:2.1.5 JDK

  • 关于QueryWrapper,实现MybatisPlus多表关联查询方式

    目录 QueryWrapper实现MybatisPlus多表关联查询 1.dao层接口使用Select注解写SQL 2.service层代码示例 3.反射工具类 4.判空工具类 MybatisPlus QueryWrapper简单用法 QueryWrapper实现MybatisPlus多表关联查询 1.dao层接口使用Select注解写SQL 重点:@Param("ew") Wrapper参数是必须,因为${ew.customSqlSegment} 底层其实就是where 条件,所以为

  • MyBatis-plus 模糊查询的使用

    在使用MyBatis-plus的时候,一些基础的增删改查可以不用再自己写sql了: public interface UserDao extends BaseMapper<FykUser>{ } 就这样,就可以实现user表的增删改查了. 模糊查询 使用userDao.selectList(queryWrapper)方法,就可以查询出一个用户列表. 如果需要模糊查询,代码如下: //条件封装 QueryWrapper<FykUser> queryWrapper = new Quer

  • mybatisplus 的SQL拦截器实现关联查询功能

    由于项目中经常会使用到一些简单地关联查询,但是mybatisplus还不支持关联查询,不过在看官方文档的时候发现了mybatisplus的SQL拦截器(其实也是mybatis的)就想着能不能在SQL执行的时候做一些处理以至于可以支持关联查询,于是就动手开始了,目前还只是一个初步的demo,但是一些基本的关联查询功能经过验证是没有问题的 环境信息 jdk: 1.8 springboot: 2.3.4.RELEASE mybatisplus: 3.4.2 lombok:1.18.12 代码设计 代码

随机推荐