20191209-mybatisplus(二) 条件构造器

AbstractWrapper

QueryWrapper(LambdaQueryWrapper)和UpdateWrapper(LambdaUpdateWrapper)的父类,用于生成sql的where条件, entity属性也用于生成sql的where条件

在这里插入图片描述

entity生成的 where 条件与 使用各个 api 生成的 where 条件 没有任何关联行为 !!!

  • Mybatis-Plus 通过 QueryWrapper(MP封装的一个查询条件构造器,继承自AbstractWrapper,AbstractWrapper实现了 Wrapper等接口)来让用户自由的构建查询条件,简单便捷,没有额外的负担,能够有效提高开发效率

  • 查询包装器QueryWrapper, 主要用于处理 sql 拼接,排序,实体参数查询等

  • 注意: 使用的是 数据库字段 ,不是 Java 属性!

  • 需要这些功能时,只需要创建 QueryWrapper对象 即可

模糊查询

  • like ===> %值% ==> queryWrapper.like(数据库中的列名,查询条件)
  • .lt <小于
  @Test
    public void selectByWrapper(){
        QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
        QueryWrapper<User> query= Wrappers.<User>query();
        queryWrapper.like("name","雨").lt("age",40);
        List<User> userList=userMapper.selectList(queryWrapper);
        userList.forEach(System.out::println);
    }

=> SELECT id,create_time,name,manager_id,email,age FROM user WHERE (name LIKE ‘%雨%’ AND age < 40)

  • isNotNull 字段 IS NOT NULL
  • between (R column, Object val1, Object val2)==> BETWEEN 值1 AND 值2
 @Test
    public void selectByWrapper2(){
        QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
        queryWrapper.like("name","雨").between("age",20,40).isNotNull("email");
        List<User> userList=userMapper.selectList(queryWrapper);
        userList.forEach(System.out::println);
    }

=> SELECT id,create_time,name,manager_id,email,age FROM user WHERE (name LIKE ‘%雨%’ AND age BETWEEN 20 AND 40 AND email IS NOT NULL)

  • orderByAsc (R… columns) 升序
  • orderByDesc (R… columns) 降序
  • likeRight (R column, Object val) ==> LIKE ‘值%’
名字为王姓或者年龄大于等于25,按照年龄降序排列,年龄相同按照id升序排列
   @Test
    public void selectByWrapper3(){
        QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
        queryWrapper.likeRight("name","王").or().ge("age",25).orderByDesc("age")
                .orderByAsc("id");
        List<User> userList=userMapper.selectList(queryWrapper);
        userList.forEach(System.out::println);
    }

=> SELECT id,create_time,name,manager_id,email,age FROM user WHERE (name LIKE 王% OR age >= 25) ORDER BY age DESC , id ASC

嵌套查询

  • inSql (R column, String inValue)==>字段 IN ( sql语句 )

  • apply (String applySql, Object… params)==>拼接 sql

  • 该方法可用于数据库函数 动态入参的params对应前面applySql内部的{index}部分.这样是不会有sql注入风险的,反之会有!
    

第一种方式:存在sql语句注入的风险 建议不要使用该方式

queryWrapper.apply("date_format(create_time,'%Y-%m-%d')='2019-02-14'")
==》SELECT id,create_time,name,manager_id,email,age FROM user WHERE (date_format(create_time,'%Y-%m-%d')='2019-02-14'

queryWrapper.apply("date_format(create_time,'%Y-%m-%d')={0}","2019-02-14")
==> SELECT id,create_time,name,manager_id,email,age FROM user WHERE (date_format(create_time,'%Y-%m-%d')=? 
   
  创建日期为2019年2月14日并且直属上级为名字为王姓
        date_format(create_time,'%Y-%m-%d')='2019-02-14' and manager_id in (select id from user where name like '王%')
  
    @Test
    public void selectByWrapper4(){
        QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
        queryWrapper.apply("date_format(create_time,'%Y-%m-%d')={0}","2019-02-14")
                .inSql("manager_id","select id from user where name like '王%'");
        List<User> userList=userMapper.selectList(queryWrapper);
        userList.forEach(System.out::println);
    }

==> SELECT id,create_time,name,manager_id,email,age FROM user WHERE (date_format(create_time,’%Y-%m-%d’)=? AND manager_id IN (select id from user where name like ‘王%’))

and嵌套 or嵌套

  • or(Consumer consumer)
  • and(Consumer consumer)
 
 名字为王姓并且(年龄小于40或邮箱不为空)
       name like '王%' and (age<40 or email is not null)
     
    @Test
    public void selectByWrapper5(){
        QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
        queryWrapper.likeRight("name","王").and(wq->wq.lt("age",40).or().isNotNull("email"));
        List<User> userList=userMapper.selectList(queryWrapper);
        userList.forEach(System.out::println);
    }

=》SELECT id,create_time,name,manager_id,email,age FROM user WHERE (name LIKE ? AND ( (age < ? OR email IS NOT NULL) ))

  • .gt() =>大于

 名字为王姓或者(年龄小于40并且年龄大于20并且邮箱不为空)
     name like '王%' or (age<40 and age>20 and email is not null)
    
     
    @Test
    public void selectByWrapper6(){
        QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
        queryWrapper.likeRight("name","王")
                .or(wq->wq.lt("age",40).gt("age",20).isNotNull("email"));
        List<User> userList=userMapper.selectList(queryWrapper);
        userList.forEach(System.out::println);
    }

==>SELECT id,create_time,name,manager_id,email,age FROM user WHERE (name LIKE ? OR ( (age < ? AND age > ? AND email IS NOT NULL) ))

nested 正常嵌套

  • nested(Consumer consumer)正常嵌套 不带 AND 或者 OR

    => or的优先级小于and的优先级 所以 or要用(条件) 否则先执行and()

(年龄小于40或邮箱不为空)并且名字为王姓
   (age<40 or email is not null) and name like '王%'
    
    @Test
    public void selectByWrapper7(){
        QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
        queryWrapper.nested(wp->wp.lt("age",40).or().isNotNull("email"))
                .likeRight("name","王");
        List<User> userList=userMapper.selectList(queryWrapper);
        userList.forEach(System.out::println);
    }

==> SELECT id,create_time,name,manager_id,email,age FROM user WHERE (( (age < ? OR email IS NOT NULL) ) AND name LIKE ?)

last

last()无视优化规则直接拼接到 sql 的最后

  • 只能调用一次,多次调用以最后一次为准 有sql注入的风险,请谨慎使用

  • 如果确保该字段没有注入风险可以使用

 @Test
    public void selectByWrapper9(){
        QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
        queryWrapper.in("age",Arrays.asList(30,31,34,35)).last("limit 1");
        List<User> userList=userMapper.selectList(queryWrapper);
        userList.forEach(System.out::println);
    }

==> SELECT id,create_time,name,manager_id,email,age FROM user WHERE (age IN (?,?,?,?)) limit 1

查询指定部分列

QueryWrapper条件

继承自 AbstractWrapper ,自身的内部属性 entity 也用于生成 where 条件
及 LambdaQueryWrapper, 可以通过 new QueryWrapper().lambda() 方法获取

方法一:
 QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
方法二:
 QueryWrapper<User> query= Wrappers.<User>query();

情况一:筛选出指定字段
select id,name from user where name like ‘%雨%’ and age<40

  @Test
    public void selectByWrapperSupper(){
        QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
        queryWrapper.select("id","name").like("name","雨").lt("age",40);
        List<User> userList=userMapper.selectList(queryWrapper);
        userList.forEach(System.out::println);
    }

情况二:排除非指定字段 select id,name,age,email from user where name like ‘%雨%’ and age<40

@Test
    public void selectByWrapperSupper2(){
        QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
        /**
         * info.getColumn() 获取列名
         */
        queryWrapper.like("name","雨").lt("age",40).select(User.class,info->!info.getColumn().equals("create_time")&&!info.getColumn().equals("manager_id"));
        List<User> userList=userMapper.selectList(queryWrapper);
        userList.forEach(System.out::println);
    }

condition的作用

  • condition的作用是为true时,执行其中的SQL条件,为false时,忽略设置的SQL条件
    @Test
    public void testCondition(){
        String name="王";
        String email="";
        condition(name,email);
    }

    private void condition(String name,String email){
        QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
        /**
         * StringUtils.isNotEmpty(name)判断是否为空或者空串
         */
//        if(StringUtils.isNotEmpty(name)){
//            queryWrapper.like("name",name);
//        }
//        if(StringUtils.isNotEmpty(email)){
//            queryWrapper.like("email",email);
//        }
        // =>SELECT id,create_time,name,manager_id,email,age FROM user WHERE (name LIKE ?)

        queryWrapper.like(StringUtils.isNotEmpty(name),"name",name)
                .like(StringUtils.isNotEmpty(email),"email",email);
        List<User> userList=userMapper.selectList(queryWrapper);
        userList.forEach(System.out::println);
    }

==> SELECT id,create_time,name,manager_id,email,age FROM user WHERE (name LIKE ?)

实体作为条件构造方法的参数

如果想通过对象中某些属性进行模糊查询,我们可以在跟数据库表对应的实体类中相应的属性 标注注解 即可。

  • 以实体作为条件构造器 构造方法传入实体 =>会和普通条件构造器同时加载 一般是等值的
@Data
public class User {
    //主键
    private Long id;
   //姓名
    @TableField(condition = SqlCondition.LIKE)
    private String name;
    //年龄
    /**
     * 小于  @TableField(condition = "%s&lt;#{%s}")
     */
    @TableField(condition = "%s&lt;#{%s}")
    private Integer age;
    //邮箱

    private String email;
    //直属上级
    private Long managerId;
    //创建时间
    private LocalDateTime createTime;


}

   @Test
    public void selectByWrapperEntity(){
        User whereUser=new User();
        whereUser.setName("刘宇浩");
        whereUser.setAge(29);
        QueryWrapper<User> queryWrapper=new QueryWrapper<User>(whereUser);
        queryWrapper.like("name","雨").lt("age",40);
        List<User> userList=userMapper.selectList(queryWrapper);
        userList.forEach(System.out::println);
    }

queryWrapper .like(“name”,“雨”).lt(“age”,40) ;

=》SELECT id,create_time,name,manager_id,email,age FROM user WHERE name=? AND age=? AND (name LIKE ? AND age < ?)

   @Test
    public void selectByWrapperEntity(){
        User whereUser=new User();
        whereUser.setName("刘宇浩");
        whereUser.setAge(29);
        QueryWrapper<User> queryWrapper=new QueryWrapper<User>(whereUser);
        List<User> userList=userMapper.selectList(queryWrapper);
        userList.forEach(System.out::println);
    }

@TableField(condition = SqlCondition.LIKE)

private String name;

=》SELECT id,create_time,name,manager_id,email,age FROM user WHERE name LIKE CONCAT(’%’,?,’%’) AND age=?

   @Test
    public void selectByWrapperEntity(){
        User whereUser=new User();
        whereUser.setName("刘宇浩");
        whereUser.setAge(29);
        QueryWrapper<User> queryWrapper=new QueryWrapper<User>(whereUser);
        List<User> userList=userMapper.selectList(queryWrapper);
        userList.forEach(System.out::println);
    }

@TableField(condition = SqlCondition.LIKE)

private String name;

@TableField(condition = “%s<#{%s}”)

private Integer age;

=>SELECT id,create_time,name,manager_id,email,age FROM user WHERE name LIKE CONCAT(’%’,?,’%’) AND age<?

Lambda条件构造器

MybatisPlus提供了 4种 方式创建lambda条件构造器

  1. LambdaQueryWrapper<User> lambdaQueryWrapper=new QueryWrapper<User>().lambda();
  2. LambdaQueryWrapper<User> lambdaQueryWrapper2=new LambdaQueryWrapper<User>();
  3. LambdaQueryWrapper<User> lambdaQueryWrapper3=Wrappers.<User>lambdaQuery();
  4. List<User> userList= new LambdaQueryChainWrapper<User>(userMapper)
                .like(User::getName,"雨").ge(User::getAge,20).list();
  • QueryWrapper类已经提供了很强大的功能,而lambda条件构造器做的和QueryWrapper的事也是相同的为什么要冗余的存在lambda条件构造器呢?

QueryWrapper是通过自己写表中相应的属性进行构造where条件的,容易发生拼写错误,在编译时不会报错,只有运行时才会报错,而lambda条件构造器是通过调用实体类中的方法,如果方法名称写错,直接进行报错,所以lambda的纠错功能比QueryWrapper要提前很多

 @Test
    public void selectLambda(){
        LambdaQueryWrapper<User> lambdaQueryWrapper3=Wrappers.<User>lambdaQuery();
        lambdaQueryWrapper3.like(User::getName,"雨").lt(User::getAge,40);
        //where name like '%雨%'
        List<User> userList=userMapper.selectList(lambdaQueryWrapper3);
        userList.forEach(System.out::println);
    }

 @Test
    public void selectLambda3(){
        List<User> userList= new LambdaQueryChainWrapper<User>(userMapper)
                .like(User::getName,"雨").ge(User::getAge,20).list();
        userList.forEach(System.out::println);
    }

猜你喜欢

转载自blog.csdn.net/fggsgnhz/article/details/103537617