六、Example 用法

通用 Mapper 中的 Example 方法有两大类定义,一个参数和两个参数的,例如下面两个:

  1. List<T> selectByExample(Object example);
  2. int updateByExampleSelective(@Param("record") T record, @Param("example") Object example);

所有 Example 方法中的 example 类型都是 Object 类型,这是因为通用 Mapper 支持所有符合 Example 结构的参数,例如通过 MBG 生成的 CountryExample、UserExample 类。还有通用 Mapper 中提供的通用 Example,以及支持 Java8 方法引用的 Weekend 类型。

配置中有一个和 Example 有关的参数,点击查看 3.14 checkExampleEntityClass

6.1 MBG 生成的 Example

用法如下:

  1. CountryExample example = new CountryExample();
  2. example.createCriteria().andCountrynameLike("A%");
  3. example.or().andIdGreaterThan(100);
  4. example.setDistinct(true);
  5. int count = mapper.deleteByExample(example);

对于的 SQL 日志如下:

  1. DEBUG [main] - ==> Preparing: DELETE FROM country WHERE ( countryname like ? ) or ( Id > ? )
  2. DEBUG [main] - ==> Parameters: A%(String), 100(Integer)
  3. DEBUG [main] - <== Updates: 95

生成的 CountryExample 中包含了和字段相关的多种方法,根据自己的需要设置相应的条件即可。

6.2 通用 Example

这是由通用 Mapper 提供的一个类,这个类和 MBG 生成的相比,需要自己设置属性名。这个类还额外提供了更多的方法。

6.2.1 查询

示例:

  1. Example example = new Example(Country.class);
  2. example.setForUpdate(true);
  3. example.createCriteria().andGreaterThan("id", 100).andLessThan("id",151);
  4. example.or().andLessThan("id", 41);
  5. List<Country> countries = mapper.selectByExample(example);

日志:

  1. DEBUG [main] - ==> Preparing: SELECT id,countryname,countrycode FROM country WHERE ( id > ? and id < ? ) or ( id < ? ) ORDER BY id desc FOR UPDATE
  2. DEBUG [main] - ==> Parameters: 100(Integer), 151(Integer), 41(Integer)
  3. DEBUG [main] - <== Total: 90

6.2.2 动态 SQL

示例:

  1. Example example = new Example(Country.class);
  2. Example.Criteria criteria = example.createCriteria();
  3. if(query.getCountryname() != null){
  4. criteria.andLike("countryname", query.getCountryname() + "%");
  5. }
  6. if(query.getId() != null){
  7. criteria.andGreaterThan("id", query.getId());
  8. }
  9. List<Country> countries = mapper.selectByExample(example);

日志:

  1. DEBUG [main] - ==> Preparing: SELECT id,countryname,countrycode FROM country WHERE ( countryname like ? ) ORDER BY id desc
  2. DEBUG [main] - ==> Parameters: China%(String)
  3. DEBUG [main] - <== Total: 1

6.2.3 排序

示例:

  1. Example example = new Example(Country.class);
  2. example.orderBy("id").desc().orderBy("countryname").orderBy("countrycode").asc();
  3. List<Country> countries = mapper.selectByExample(example);

日志:

  1. DEBUG [main] - ==> Preparing: SELECT id,countryname,countrycode FROM country order by id DESC,countryname,countrycode ASC
  2. DEBUG [main] - ==> Parameters:
  3. DEBUG [main] - <== Total: 183

6.2.4 去重

示例:

  1. CountryExample example = new CountryExample();
  2. //设置 distinct
  3. example.setDistinct(true);
  4. example.createCriteria().andCountrynameLike("A%");
  5. example.or().andIdGreaterThan(100);
  6. List<Country> countries = mapper.selectByExample(example);

日志:

  1. DEBUG [main] - ==> Preparing: SELECT distinct id,countryname,countrycode FROM country WHERE ( countryname like ? ) or ( Id > ? ) ORDER BY id desc
  2. DEBUG [main] - ==> Parameters: A%(String), 100(Integer)
  3. DEBUG [main] - <== Total: 95

6.2.5 设置查询列

示例:

  1. Example example = new Example(Country.class);
  2. example.selectProperties("id", "countryname");
  3. List<Country> countries = mapper.selectByExample(example);

日志:

  1. DEBUG [main] - ==> Preparing: SELECT id , countryname FROM country ORDER BY id desc
  2. DEBUG [main] - ==> Parameters:
  3. DEBUG [main] - <== Total: 183

除了这里提到的方法外,还有很多其他的方法,可以查看 Example 源码进行了解。

6.3 Example.builder 方式

示例:

  1. Example example = Example.builder(Country.class)
  2. .select("countryname")
  3. .where(Sqls.custom().andGreaterThan("id", 100))
  4. .orderByAsc("countrycode")
  5. .forUpdate()
  6. .build();
  7. List<Country> countries = mapper.selectByExample(example);

日志:

  1. DEBUG [main] - ==> Preparing: SELECT countryname FROM country WHERE ( id > ? ) order by countrycode Asc FOR UPDATE
  2. DEBUG [main] - ==> Parameters: 100(Integer)
  3. DEBUG [main] - <== Total: 83

6.4 Weekend

使用 6.2 和 6.3 中的 Example 时,需要自己输入属性名,例如 "countryname",假设输入错误,或者数据库有变化,这里很可能就会出错,因此基于 Java 8 的方法引用是一种更安全的用法,如果你使用 Java 8,你可以试试 Weekend。

示例:

  1. List<Country> selectByWeekendSql = mapper.selectByExample(new Example.Builder(Country.class)
  2. .where(WeekendSqls.<Country>custom().andLike(Country::getCountryname, "%a%")
  3. .andGreaterThan(Country::getCountrycode, "123"))
  4. .build());

日志:

  1. DEBUG [main] - ==> Preparing: SELECT id,countryname,countrycode FROM country WHERE ( countryname like ? and countrycode > ? )
  2. DEBUG [main] - ==> Parameters: %a%(String), 123(String)
  3. DEBUG [main] - <== Total: 151

在代码中的 Country::getCountryname 就是方法引用,通过该方法可以自动转换对应的列名。