title: 1.2.0

2022年4月9日 - 1.2.0 发布

mybatis-provider 项目升级到 1.1.1

  1. 升级依赖版本
  2. 替换log4j为logback(测试用)
  3. 去掉了一个 System.out.println 输出

mybatis-mapper 项目升级到 1.2.0

  1. 升级依赖版本
  2. 替换log4j为logback(测试用)
  3. Example 增加 set 方法设置要更新的字段,ExampleMapper 增加 updateByExampleSetValues 方法使用设置的 set 更新数据。
  4. 新增加 ExampleWrapper 类,封装了 Example 方法,该类可以通过 BaseMapper.wrapper() 直接获取使用,通过链式调用方便使用。代码示例:

BaseMapper.wrapper() 示例

  1. //获取 Mapper,在 Spring 中可以直接注入使用
  2. UserMapper2 mapper = sqlSession.getMapper(UserMapper2.class);
  3. //查询 "sex=男 or name like '杨%' 的数量
  4. long count = mapper.wrapper().eq(User::getSex, "男")
  5. .or(
  6. c -> c.startsWith(User::getUserName, "杨")
  7. ).count();
  8. Assert.assertEquals(1, count);
  9. //查询 "sex=男 or (name like '杨%' or (name like '俞%' and name like '%舟')) 的数量
  10. count = mapper.wrapper().eq(User::getSex, "男")
  11. .or(
  12. c -> c.startsWith(User::getUserName, "杨"),
  13. c -> c.startsWith(User::getUserName, "俞").endsWith(User::getUserName, "舟")
  14. ).count();
  15. Assert.assertEquals(2, count);
  16. //查询 name 和 sex 列,条件为 (name like '杨%' or sex = '男') or id > 1 and id <= 16 and sex = '女' 的数据
  17. List<User> users = mapper.wrapper()
  18. .select(User::getUserName, User::getSex)
  19. .or(c -> c.startsWith(User::getUserName, "杨"),
  20. c -> c.eq(User::getSex, "男"))
  21. .or()
  22. .gt(User::getId, 1L)
  23. .le(User::getId, 16L)
  24. .eq(User::getSex, "女").list();
  25. //构建的wrapper可以多次使用
  26. //查询条件为 id > 50 or id <= 5 or sex = '女'
  27. ExampleWrapper<User, Long> wrapper = mapper.wrapper()
  28. .gt(User::getId, 50L)
  29. .or()
  30. .le(User::getId, 5L)
  31. .or()
  32. .eq(User::getSex, "女");
  33. //使用当前条件获取前5条数据
  34. users = wrapper.top(5);
  35. Assert.assertEquals(5, users.size());
  36. //追加条件后查询数量
  37. count = wrapper.select(User::getSex).distinct().count();
  38. Assert.assertEquals(2, count);
  39. //根据条件"name=张无忌",更新名字和性别
  40. Assert.assertEquals(1, mapper.wrapper()
  41. .set(User::getUserName, "弓长无忌")
  42. .set(User::getSex, "M")
  43. .eq(User::getUserName, "张无忌").update());
  44. //根据条件"sex=M"查询数量
  45. Assert.assertEquals(1, mapper.wrapper().eq(User::getSex, "M").count());

warpper 封装的方法中,相比 Example 增加了 contains, startsWith, endsWith 3个模糊查询方法,原有的 like 和 notLike 仍然需要手动添加 ‘%’。

  • contains 在两侧加上 %,如 %内容%
  • startsWith 在右侧加上 %,如 内容%
  • endsWith 在左侧加上 %,如 %内容

上面代码中所有方法对应的数据库日志如下:

  1. countByExample - ==> Preparing: SELECT COUNT( * ) FROM user WHERE ( sex = ? AND ( ( name LIKE ? ) ) )
  2. countByExample - ==> Parameters: 男(String), 杨%(String)
  3. countByExample - <== Total: 1
  4. countByExample - ==> Preparing: SELECT COUNT( * ) FROM user WHERE ( sex = ? AND ( ( name LIKE ? ) OR ( name LIKE ? AND name LIKE ? ) ) )
  5. countByExample - ==> Parameters: 男(String), 杨%(String), 俞%(String), %舟(String)
  6. countByExample - <== Total: 1
  7. selectByExample - ==> Preparing: SELECT name AS userName,sex FROM user WHERE ( ( ( name LIKE ? ) OR ( sex = ? ) ) ) OR ( id > ? AND id <= ? AND sex = ? )
  8. selectByExample - ==> Parameters: 杨%(String), 男(String), 1(Long), 16(Long), 女(String)
  9. selectByExample - <== Total: 44
  10. selectByExample - ==> Preparing: SELECT id,name AS userName,sex FROM user WHERE ( id > ? ) OR ( id <= ? ) OR ( sex = ? )
  11. selectByExample - ==> Parameters: 50(Long), 5(Long), 女(String)
  12. countByExample - ==> Preparing: SELECT COUNT( distinct sex ) FROM user WHERE ( id > ? ) OR ( id <= ? ) OR ( sex = ? )
  13. countByExample - ==> Parameters: 50(Long), 5(Long), 女(String)
  14. countByExample - <== Total: 1
  15. updateByExampleSetValues - ==> Preparing: UPDATE user SET name = ?, sex = ? WHERE ( name = ? )
  16. updateByExampleSetValues - ==> Parameters: 弓长无忌(String), M(String), 张无忌(String)
  17. updateByExampleSetValues - <== Updates: 1
  18. countByExample - ==> Preparing: SELECT COUNT( * ) FROM user WHERE ( sex = ? )
  19. countByExample - ==> Parameters: M(String)
  20. countByExample - <== Total: 1

特别注意 or()or(Function<Example.OrCriteria<T>, Example.OrCriteria<T>>... orParts) 方法。

or() 是后面的条件和前面用 or 连接。

带参数的 or(...) 是一个嵌套的块,块中的每个部分使用 or 连接,块内使用 and,当前 or(...) 这部分和前面是 and 连接。

如下面代码:

  1. mapper.wrapper()
  2. .eq(User::getSex, "女")
  3. .or(c -> c.gt(User::getId, 40), c -> c.lt(User::getId, 10)).list();

对应的查询条件为:sex = '女' and (id > 40 or id < 10),运行时输出的 SQL 如下:

  1. selectByExample - ==> Preparing: SELECT id,name AS userName,sex FROM user WHERE ( sex = ? AND ( ( id > ? ) OR ( id < ? ) ) )
  2. selectByExample - ==> Parameters: 女(String), 40(Integer), 10(Integer)
  3. selectByExample - <== Columns: ID, USERNAME, SEX
  4. selectByExample - <== Row: 41, 武青婴,
  5. selectByExample - <== Row: 46, 郭襄,
  6. selectByExample - <== Row: 50, 韩姬,
  7. selectByExample - <== Row: 51, 黄衫女子,
  8. selectByExample - <== Row: 2, 赵敏,
  9. selectByExample - <== Row: 3, 周芷若,
  10. selectByExample - <== Row: 4, 小昭,
  11. selectByExample - <== Row: 5, 殷离,
  12. selectByExample - <== Row: 7, 殷素素,
  13. selectByExample - <== Total: 9

在上面基础上增加一个 or() 如下:

  1. mapper.wrapper()
  2. .eq(User::getSex, "女")
  3. .or(c -> c.gt(User::getId, 40), c -> c.lt(User::getId, 10))
  4. .or()
  5. .startsWith(User::getUserName, "张").list();

此时的日志如下:

  1. selectByExample - ==> Preparing: SELECT id,name AS userName,sex FROM user WHERE ( sex = ? AND ( ( id > ? ) OR ( id < ? ) ) ) OR ( name LIKE ? )
  2. selectByExample - ==> Parameters: 女(String), 40(Integer), 10(Integer), 张%(String)
  3. selectByExample - <== Columns: ID, USERNAME, SEX
  4. selectByExample - <== Row: 2, 赵敏,
  5. selectByExample - <== Row: 3, 周芷若,
  6. selectByExample - <== Row: 4, 小昭,
  7. selectByExample - <== Row: 5, 殷离,
  8. selectByExample - <== Row: 6, 张翠山,
  9. selectByExample - <== Row: 7, 殷素素,
  10. selectByExample - <== Row: 9, 张三丰,
  11. selectByExample - <== Row: 13, 张松溪,
  12. selectByExample - <== Row: 41, 武青婴,
  13. selectByExample - <== Row: 46, 郭襄,
  14. selectByExample - <== Row: 47, 张君宝,
  15. selectByExample - <== Row: 50, 韩姬,
  16. selectByExample - <== Row: 51, 黄衫女子,
  17. selectByExample - <== Total: 13

这里 or() 是前后两大块之间的 or,SQL 格式化一下:

  1. SELECT id,name AS userName,sex FROM user
  2. WHERE
  3. ( sex = ? AND ( ( id > ? ) OR ( id < ? ) ) )
  4. OR
  5. ( name LIKE ? )

or(...) 对应的 AND ( ( id > ? ) OR ( id < ? ) ),是 AND 连接,块内通过 OR 连接。

最后执行的结果是在前面基础上,把所有姓张的也都查询出来了。