使用 JDK1.8 default 关键字解决 MyBatis 不支持方法重载问题
配置:
mybatis >= 3.4.2
JDK >= 1.8
问题
MyBatis 是不支持在接口中定义重载方法(如下代码片段)
的,然而方法重载是一个兼容复杂业务重要手段。
场景
用户
和账户
,每个用户可以拥有多个账户,这是一个 1:N 的关系。我们简单定义它们的属性:
- Owner.java
我并不会使用到 Owner 这个对象,写出来只是让大家有个简单理解。
我们尝试实现如下 2 个功能:
- 根据状态
status
获取所有 Account;
- 根据状态
status
和所有者owner
获取所有 Account;
一个可能方案(使用注解@Param
只是我的习惯,不是必要,只要参数名字能对上即可):
上面的实现是因为传入的参数数量不一致,所以需要拆开两个方法(深层次原因是因为mybatis不支持相同的方法名字但参数不同但方法,简单说重载方法会出现问题)
。当参数的数量不断增加,日后可能需要写更多的方法,如何解决?
相信聪明的你已经想到:
- 提供全部参数签名的方法,结合动态 SQL 实现
- 使用 HashMap 来包裹参数,结合动态 SQL 实现
一个可能的写法:
或者:
上面两种方法,都可以实现需求,但是无论哪种实现,都有其缺憾
:
- 带所有参数都方法:每次都需要显式传递 null 或 - 1 来辨别是否有值,
调用方式丑陋
- 使用 Map 包裹:调用者无法知道有所有可选参数以及参数的名字,
调用参数不清晰
优雅的方案
使用 JDK1.8 提供的 default 关键字,并结合动态 SQL 可以很好的处理这个问题:
- AccountMapper.java
这里实现了方法的重载
,较少参数的方法使用default
关键字实现,调用其他重载方法并出入默认值。
- AccountMapper.xml
status
是一个强制的参数(当前这个场景),而owner
则属于可选参数(可以附带更多其他可选参数)。
欢迎大家留言讨论,另外完整的例子:mybatis-examples