目标:
SELECT * FROM tb_brand WHERE (id > 3000 AND name LIKE '%星%') OR name = 'vivo';
// 创建Example对象
Example example = new Example(Brand.class);
// 通过Example对象创建Criteria对象
Example.Criteria criteria1 = example.createCriteria();
Example.Criteria criteria2 = example.createCriteria();
// 在Criteria1对象中设置查询条件: 查询id大于3000且名称带"星"的品牌
criteria1.andGreaterThan("id", 3000).andLike("name", "%星%");
// 在Criteria2对象中设置查询条件: 查询名称是"vivo"的品牌
criteria2.andEqualTo("name", "vivo");
// 使用Or关键字组装两个Criteria
example.or(criteria2);
// 执行查询
List<Brand> brands = brandMapper.selectByExample(example);
for (Brand brand : brands) {
System.out.println(brand);
}
对于 example.or(criteria2)
的分析
为什么只需要加一个条件而不是下方这样
example.or(criteria1);
example.or(criteria2);
因为如果不写or连接也可以直接根据第一个条件查询,现在是需要在第一个查询条件中加上另一个查询条件,所以只需要写一个。
如何判断第一个查询条件?根据谁先创建。
// 因为是criteria1先创建,所以只需拼接criteria2即可
// 若是不拼接,就默认根据criteria1查询
// 若criteria1和criteria2交换了位置,那么就默认根据criterial2查询
Example.Criteria criteria1 = example.createCriteria();
Example.Criteria criteria2 = example.createCriteria();
上述情况源码解释
在Example
类中有这么一个参数用于存放Criteria
protected List<Criteria> oredCriteria;
创建Criteria
调用的是createCriteria()
方法,说明如果是第一个Criteria则会默认加入List。
public Criteria createCriteria() {
// 新建一个criteria
Criteria criteria = createCriteriaInternal();
// 如果List中没有元素,则默认增加一个,并用and连接。
if (oredCriteria.size() == 0) {
criteria.setAndOr("and");
oredCriteria.add(criteria);
}
return criteria;
}
上述代码可默认类比为如下Sql语句
如果不加Criteria
SELECT * FROM tb_brand WHERE 1=1
如果加了Criteria,下方的AND拼接即是criteria.setAndOr("and")
这段代码的实现
SELECT * FROM tb_brand WHERE 1=1 AND (id > 3000 AND name LIKE '%星%')
为什么要用多个Criteria
设想这样的Sql业务场景
SELECT * FROM tb_brand WHERE 1=1
AND (id > 3000 AND name LIKE '%星%')
OR (id < 1000 AND name LIKE '%贝%')
上述Sql如果用一个Criteria是这么写
criteria.andGreaterThan("id", 3000).andLike("name", "%星%")
.orLessThan("id", 1000).andLike("name", "%贝%");
而实际执行的Sql是这样的,就容易产生歧义
SELECT * FROM tb_brand WHERE 1=1
AND id > 3000 AND name LIKE '%星%'
OR id < 1000 AND name LIKE '%贝%'
所以需要使用多个Criteria进行拼接