MyBatisGenerator查询方法的使用中的Example对象

MyBatisGenerator查询方法的使用中的Example对象

背景:

MyBatisGenerator(MBG)是MyBatis官方提供的代码生成器。它可以根据数据库的表结构自动生成POJO类、持久层接口与映射文件,极大减少了代码的编写量,提高开发效率。

通过MBG自动生成的一些类和文件

上图是通过MBG生成的一些类和文件,Product类是实体类,ProductExample是执行查询语句时需要使用到的类,除了查询方法以外的方法都比较简单,不做赘述。

问题描述:

在查询时候,必须要用到ProductExample类,新建该类实例,然后通过该实例创建内部类Criteria对象,通过criteria对象向sql语句中添加条件,如下代码是模糊查询的示例,该案例查询出了name中带有“百战”并且price在0.0到20000.0之间的product

 @Test
    public void testFindAnd(){
    	//创建Example对象
        ProductExample example = new ProductExample();
        //创建criteria
        ProductExample.Criteria criteria = example.createCriteria();
        //添加模糊查询条件
        criteria.andProductnameLike("%百战%");
        criteria.andPriceBetween(0.0,20000.0);
        //执行sql语句
        List<Product> all = productMapper.selectByExample(example);
        //输出结果
        all.forEach(System.out::println);
    }

在执行查询语句时,可以理解为一个Example对象对应一条sql语句,而每个Example对象可以创建多个Criteria对象。一般情况下,新建一个Example对象后,会通过这个对象去创建一个criteria对象(含有or的方法除外),通过这一个criteria不停的调用一系列and方法向sql语句中添加条件。让我疑惑的是,如果同一个Example对象创建了多个criteria,每个criteria控制一个条件,那么执行sql语句时,会把所有条件都加入吗?N个criteria对象,每个控制一个条件,是否等同于一个criteria对象控制N个条件?

测试过程分析:

针对上述问题进行如下测试
Product表:
product表
1.一个criteria,添加一个条件

@Test
    public void test1(){
        //创建example对象
        ProductExample example = new ProductExample();
        //通过该example创建第一个criteria
        ProductExample.Criteria criteria = example.createCriteria();
        //通过criteria添加查询条件
        criteria.andProductnameLike("%百战%");
        //执行查询语句
        List<Product> all = productMapper.selectByExample(example);
        //输出
        all.forEach(System.out::println);
    }

执行结果
执行结果

2.一个criteria,添加两个条件

@Test
    public void test2(){
        //创建example对象
        ProductExample example = new ProductExample();
        //通过该example创建第一个criteria
        ProductExample.Criteria criteria = example.createCriteria();
        //通过criteria添加两个查询条件
        criteria.andProductnameLike("%百战%");
        criteria.andPriceBetween(0.0,2.0);
        //查询并输出
        List<Product> all = productMapper.selectByExample(example);
        all.forEach(System.out::println);
    }

执行结果

添加了两个条件,没有符合的produt

3.一个example创建的两个criteria,各添加一个条件

@Test
    public void test3(){
        //创建example对象
        ProductExample example = new ProductExample();
        //通过该example创建第一个criteria
        ProductExample.Criteria criteria = example.createCriteria();
        //通过criteria添加查询条件
        criteria1.andProductnameLike("%百战%");
        //通过该example创建第二个criteria
        ProductExample.Criteria criteria1 = example.createCriteria();
        //通过criteria1添加查询条件
        criteria.andPriceBetween(0.0,20000.0);
        //查询并输出
        List<Product> all = productMapper.selectByExample(example);
        all.forEach(System.out::println);
    }

执行结果
执行结果
结果和上面查询出来的不一样。查询出了满足第一个但不满足第二条件的数据。说明第二个条件未添加进去

交换上面两个criteria添加的条件

@Test
    public void test2(){
        //创建example对象
        ProductExample example = new ProductExample();
        //通过该example创建第一个criteria
        ProductExample.Criteria criteria = example.createCriteria();
        //通过criteria添加查询条件
        criteria.andPriceBetween(0.0,20000.0);
        //通过该example创建第二个criteria
        ProductExample.Criteria criteria1 = example.createCriteria();
        //通过criteria1添加查询条件
        criteria1.andProductnameLike("%百战%");
        //查询并输出
        List<Product> all = productMapper.selectByExample(example);
        all.forEach(System.out::println);
    }

执行结果
执行结果
发现查询语句和查询出来的结果不一样。查询出了满足第一个但不满足第二个条件的数据。

得出结论:

根据这个测试结果,可以发现,N个criteria对象,每个控制一个条件,不等同于一个criteria对象控制N个条件。我目前的猜测是,当一个example创建两个criteria时,会执行带有第一个criteria添加的条件的sql语句。(仅仅是根据测试结果猜测,后续还需要看源码分析,有大佬懂的可以在评论区留言指正一下)

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值