Skip to content

Releases: mybatis-mapper/mapper

2.2.1 - 2023-12-16

16 Dec 01:02
Compare
Choose a tag to compare
  • 复杂example查询示例
  • 测试批量插入ID
  • 完善测试代码
  • JPA不加注解时排除接口、数组、枚举、基本类型、注解类型,fixed #93
  • 依赖的 mybatis-provider 升级为 2.2.3

Example 示例

Example<User> example = new Example<>();
example.createCriteria().andEqualTo(User::getSex, "男").andOr(
    example.orPart().andLike(User::getUserName, "杨%"),
    example.orPart().le(User::getId, 10));
List<User> users1 = mapper.selectByExample(example);

//wrapper写法,结果一样
List<User> list = mapper.wrapper().eq(User::getSex, "男")
    .or(
        c -> c.startsWith(User::getUserName, "杨"),
        c -> c.le(User::getId, 10)).list();

生成的 SQL:

SELECT id,name AS userName,sex,status FROM user WHERE ( sex = ? AND ( ( name LIKE ? ) OR ( id <= ? ) ) )

简化括号后:

SELECT id,name AS userName,sex,status FROM user WHERE sex = ? AND ( name LIKE ?  OR id <= ? ) 

2.2.0 - 2023-12-05

06 Dec 01:08
Compare
Choose a tag to compare
  • 升级mybatis-provider2.2.2版本,添加insert测试jpa,closed #92
  • 增加mybatis-jakarta-jpa支持jakarta.persistence-api by 曹赛军
  • jakarta需要jdk11,修改运行环境依赖的jdk版本,其他模块仍然以jdk8编译

2.1.1 - 2023-6-4

23 Aug 12:12
Compare
Choose a tag to compare
  1. 解决接口方法冲突
  2. 优化Fn中的字段处理
  3. LogicalMapper实现

2.1.0 - 2022-12-26

23 Aug 12:10
Compare
Choose a tag to compare
  1. Fn支持直接输入字段名或列名,支持使用字符串形式的参数。
  2. Fn增加方法,当通过基类或基类泛型的字段引用时,可以指定所属的实体类 fixed#50
  3. 兼容 spring boot 3.0
  4. 增加h2驱动和相关测试,去掉mysql依赖,完善批量查询功能,支持复合主键的批量更新。
  5. 批量更新支持联合主键
  6. 新增批量更新 updateList、updateListSelective
  7. Example 增加 excludeColumns 排除查询列的方法,ExampleWrapper 增加 exclude 排除查询列的方法。由于重用了之前的 selectColumns 方法,这会导致之前可以多次调用 selectColumns追加查询列变成了每次调用都会覆盖查询列,不想指定时,可以 selectColumns() 空参数设置为空。fixed #63
  8. ExampleWrapper 增加 clear 方法,方便重用 wrapper, fixed #70
  9. 解决 mapper-bom 依赖 mapper-parent 导致的依赖管理冲突问题, fixed #67
  10. 修改字段批量操作方法为 Collection 类型后,这是一个不兼容的测试接口方法
  11. 通过 .editorconfig 统一代码样式,格式化代码

2.0.0 发布 - 2022-07-31

31 Jul 02:49
Compare
Choose a tag to compare
  • mybatis-provider 升级为 2.1.1,同时引入了 mybatis-config 依赖,增加 mybatis-mapper.proerteis 用户自定义配置
  • ExampleWrapper condition 系列方法新增 Supplier 重载 #47 by darren
  • 更新代码生成器,解决NAME=>nAME错误,现在可以转换为 name
  • example / wrapper 新增字符串形式的排序方法重载 #34 by darren
  • 修复 jpa 模块 获取 Entity 类型错误的问题(排除了基本类型) #41 by darren
  • 完善和Spring的集成,完善Bean的初始化和加载,fixed #51
  • 针对 mybatis-provider 中 @Entity.Prop 注解的兼容性改动
  • 添加 bom 子模块,管理 mybatis-mapper 中所有子模块的依赖 #45(** by zhousiwei**),可以使用下面的方式管理依赖:
    <dependencyManagement>
       <dependencies>
           <dependency>
               <groupId>io.mybatis</groupId>
               <artifactId>mapper-bom</artifactId>
               <version>2.0.0</version>
               <type>pom</type>
               <scope>import</scope>
           </dependency>
       </dependencies>
    </dependencyManagement>

mybatis-provider 升级到 2.1.1 版本

mapper 依赖 provider,provider 2.1.1 版本有大量改动对 mapper 也有影响,具体改动参考对应的版本日志:

mybatis-mapper.proerteis 用户自定义配置

关于配置的详细设计和实现,参考: https://blog.csdn.net/isea533/category_11904924.html

目前可配置的参数如下:

  • mybatis.provider.style,默认值为 lower_underscore,可选值如下:
    • normal 不做转换
    • lower_underscore 驼峰转下划线
    • upper_underscore 驼峰转大写下划线
    • lower 转小写
    • upper 转大写
      支持扩展,详情看 mybatis-provider 项目

支持下面 3 个参数:

@Entity.Table(value = "user",
    props = {
        @Entity.Prop(name = "deleteByExample.allowEmpty", value = "false"),
        @Entity.Prop(name = "updateByExample.allowEmpty", value = "false"),
        @Entity.Prop(name = "updateByExampleSelective.allowEmpty", value = "false")
    }
)

上面代码可以针对单个实体进行配置,也可以在配置文件中配置全局的默认配置。

除了直接在用户自定义配置文件中配置外,也支持系统变量和环境变量,使用 Spring Boot 时,也支持 Spring Boot 的所有外部化配置方式,支持在 application.[yaml|properties] 中配置,例如 yaml 方式:

mybatis:
  provider:
    style: lower_underscore
deleteByExample:
  allowEmpty: false
updateByExample:
  allowEmpty: false
updateByExampleSelective:
  allowEmpty: false
# 还可以使用 spring boot 推荐的形式
update-by-example-selective:
  allow-empty: false

1.2.2 发布

17 Apr 15:02
Compare
Choose a tag to compare

2022年4月17日 - 1.2.2 发布

mybatis-mapper 项目升级到 1.2.2

针对 issues#29 修复的问题,mybatis-mapper 项目升级到 1.2.2。

当通过方法引用获取列信息时,使用的 Java Bean 规范,如果存在列 a_tag 对应如 aTag 这样的 Java 字段,生成的 getATag 会认为字段为 ATag,和 aTag 匹配不上导致出错。

修改后,在匹配字段时会先区分大小写进行匹配,匹配不到时会再进行不区分大小写的匹配,仍然无效时会抛出异常。

1.2.1 发布

17 Apr 15:02
Compare
Choose a tag to compare

2022年4月17日 - 1.2.1 发布

mybatis-mapper 项目升级到 1.2.1

ExampleWrapper 方法增加 boolean useCondition 参数,当值为 true 时,条件生效,反之无效

用法:

mapper.wrapper()
  .eq(StrUtil.isNotEmpty(sex), User::getSex, "女")
  .or(c -> c.gt(User::getId, 40), c -> c.lt(false, User::getId, 10))
  .or()
  .startsWith(User::getUserName, "张")
  .orderByAsc(User::getId).list();

StrUtil.isNotEmpty(sex) 结果为 true 时,该条件有效,为 false 时无效。

有效时输出的 SQL 如下:

SELECT id,name AS userName,sex FROM user WHERE ( sex = ? AND ( ( id > ? ) ) ) OR ( name LIKE ? ) ORDER BY id ASC
-- Parameters: 女(String), 40(Integer), 张%(String)

无效时输出的 SQL 如下:

SELECT id,name AS userName,sex FROM user WHERE ( ( ( id > ? ) ) ) OR ( name LIKE ? ) ORDER BY id ASC
-- Parameters: 40(Integer), 张%(String)

通过这种用法可以保证当需要判断来设置条件时,可以仍然在链式调用中使用。

注意 or()or(参数) 方法的区别,详细用法和区别请看 1.2.0 更新日志

1.2.0 发布

17 Apr 15:01
Compare
Choose a tag to compare

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() 示例

//获取 Mapper,在 Spring 中可以直接注入使用
UserMapper2 mapper = sqlSession.getMapper(UserMapper2.class);
//查询 "sex=男 or name like '杨%' 的数量
long count = mapper.wrapper().eq(User::getSex, "男")
  .or(
      c -> c.startsWith(User::getUserName, "杨")
  ).count();
Assert.assertEquals(1, count);
//查询 "sex=男 or (name like '杨%' or (name like '俞%' and name like '%舟')) 的数量
count = mapper.wrapper().eq(User::getSex, "男")
  .or(
      c -> c.startsWith(User::getUserName, "杨"),
      c -> c.startsWith(User::getUserName, "俞").endsWith(User::getUserName, "舟")
  ).count();
Assert.assertEquals(2, count);
//查询 name 和 sex 列,条件为 (name like '杨%' or sex = '男') or id > 1 and id <= 16 and sex = '女' 的数据
List<User> users = mapper.wrapper()
  .select(User::getUserName, User::getSex)
  .or(c -> c.startsWith(User::getUserName, "杨"),
      c -> c.eq(User::getSex, "男"))
  .or()
  .gt(User::getId, 1L)
  .le(User::getId, 16L)
  .eq(User::getSex, "女").list();

//构建的wrapper可以多次使用
//查询条件为 id > 50 or id <= 5 or sex = '女'
ExampleWrapper<User, Long> wrapper = mapper.wrapper()
  .gt(User::getId, 50L)
  .or()
  .le(User::getId, 5L)
  .or()
  .eq(User::getSex, "女");
//使用当前条件获取前5条数据
users = wrapper.top(5);
Assert.assertEquals(5, users.size());
//追加条件后查询数量
count = wrapper.select(User::getSex).distinct().count();
Assert.assertEquals(2, count);

//根据条件"name=张无忌",更新名字和性别
Assert.assertEquals(1, mapper.wrapper()
  .set(User::getUserName, "弓长无忌")
  .set(User::getSex, "M")
  .eq(User::getUserName, "张无忌").update());
//根据条件"sex=M"查询数量
Assert.assertEquals(1, mapper.wrapper().eq(User::getSex, "M").count());

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

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

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

countByExample - ==>  Preparing: SELECT COUNT( * ) FROM user WHERE ( sex = ? AND ( ( name LIKE ? ) ) )
countByExample - ==> Parameters: 男(String), 杨%(String)
countByExample - <==      Total: 1
countByExample - ==>  Preparing: SELECT COUNT( * ) FROM user WHERE ( sex = ? AND ( ( name LIKE ? ) OR ( name LIKE ? AND name LIKE ? ) ) )
countByExample - ==> Parameters: 男(String), 杨%(String), 俞%(String), %舟(String)
countByExample - <==      Total: 1
selectByExample - ==>  Preparing: SELECT name AS userName,sex FROM user WHERE ( ( ( name LIKE ? ) OR ( sex = ? ) ) ) OR ( id > ? AND id <= ? AND sex = ? )
selectByExample - ==> Parameters: 杨%(String), 男(String), 1(Long), 16(Long), 女(String)
selectByExample - <==      Total: 44
selectByExample - ==>  Preparing: SELECT id,name AS userName,sex FROM user WHERE ( id > ? ) OR ( id <= ? ) OR ( sex = ? )
selectByExample - ==> Parameters: 50(Long), 5(Long), 女(String)
countByExample - ==>  Preparing: SELECT COUNT( distinct sex ) FROM user WHERE ( id > ? ) OR ( id <= ? ) OR ( sex = ? )
countByExample - ==> Parameters: 50(Long), 5(Long), 女(String)
countByExample - <==      Total: 1
updateByExampleSetValues - ==>  Preparing: UPDATE user SET name = ?, sex = ? WHERE ( name = ? )
updateByExampleSetValues - ==> Parameters: 弓长无忌(String), M(String), 张无忌(String)
updateByExampleSetValues - <==    Updates: 1
countByExample - ==>  Preparing: SELECT COUNT( * ) FROM user WHERE ( sex = ? )
countByExample - ==> Parameters: M(String)
countByExample - <==      Total: 1

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

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

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

如下面代码:

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

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

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

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

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

此时的日志如下:

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

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

SELECT id,name AS userName,sex FROM user 
WHERE 
      ( sex = ? AND ( ( id > ? ) OR ( id < ? ) ) ) 
   OR 
      ( name LIKE ? )

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

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

1.1.0 发布

03 Jan 11:10
Compare
Choose a tag to compare

2022年1月3日 - 1.1.0 发布 - 新年快乐:tada:

mybatis-provider 项目升级到 1.1.0

  1. 添加 NameConvert 接口,用于转换实体和字段名,默认为驼峰转下划线,可以通过 SPI 覆盖默认实现
  2. @Entity.Column 注解增加 orderByPriority 用于指定多个排序字段时的顺序,值越小优先级越高

mybatis-mapper 项目升级到 1.1.0

  1. 增加 BaseMapper,作为最基础的接口定义,原来的 Mapper 继承 BaseMapper,并且重写 insert 方法为自增
  2. JPA支持不带注解的默认实体和字段,默认情况下使用驼峰转下划线,可以通过SPI覆盖默认NameConvert 接口实现

1.0.4 发布

03 Jan 11:09
Compare
Choose a tag to compare

mybatis-activerecord 兼容 Spring Boot 2.6.0