功能对比
MyBatis-Flex 主要是和 MyBatis-Plus 与 Fluent-Mybatis 对比,内容来源其官网、git 或者 网络文章,若有错误欢迎指正。
- MyBatis-Plus:老牌的 MyBatis 增强框架
- Fluent-Mybatis:阿里云开发的 Mybatis 增强框架(来至于阿里云·云效产品团队)
| 功能或特点 |
MyBatis-Flex |
MyBatis-Plus |
Fluent-Mybatis |
| 对 entity 的基本增删改查 |
✅ |
✅ |
✅ |
| 分页查询 |
✅ |
✅ |
✅ |
| 分页查询之总量缓存 |
✅ |
❌ |
❌ |
| 分页查询无 SQL 解析设计(更轻量,及更高性能) |
✅ |
❌ |
✅ |
| 多表查询: from 多张表 |
✅ |
❌ |
❌ |
| 多表查询: left join、inner join 等等 |
✅ |
❌ |
✅ |
| 多表查询: union,union all |
✅ |
❌ |
✅ |
| 单主键配置 |
✅ |
✅ |
✅ |
| 多种 id 生成策略 |
✅ |
✅ |
✅ |
| 支持多主键、复合主键 |
✅ |
❌ |
❌ |
| 字段的 typeHandler 配置 |
✅ |
✅ |
✅ |
| 除了 Mybatis,无其他第三方依赖(更轻量) |
✅ |
❌ |
❌ |
| QueryWrapper 是否支持在微服务项目下进行 RPC 传输 |
✅ |
❌ |
未知 |
| 逻辑删除 |
✅ |
✅ |
✅ |
| 乐观锁 |
✅ |
✅ |
✅ |
| SQL 审计 |
✅ |
❌ |
❌ |
| 数据填充 |
✅ |
✔️ (收费) |
✅ |
| 数据脱敏 |
✅ |
✔️ (收费) |
❌ |
| 字段权限 |
✅ |
✔️ (收费) |
❌ |
| 字段加密 |
✅ |
✔️ (收费) |
❌ |
| 字典回显 |
✅ |
✔️ (收费) |
❌ |
| Db + Row |
✅ |
❌ |
❌ |
| Entity 监听 |
✅ |
❌ |
❌ |
| 多数据源支持 |
✅ |
借助其他框架或收费,不支持非Spring项目 |
❌ |
| 多租户 |
✅ |
✅ |
❌ |
以上内容来自第三方相关产品的官方文档或第三方平台,若有错误,欢迎纠正。
基础查询
MyBatis-Flex:
QueryCondition condition = EMPLOYEE.LAST_NAME.like("B")
.and(EMPLOYEE.GENDER.eq(1))
.and(EMPLOYEE.AGE.gt(24));
List<Employee> employees = employeeMapper.selectListByCondition(condition);
MyBatis-Plus:
QueryWrapper<Employee> queryWrapper = new QueryWrapper<>();
queryWrapper
.like("last_name","B")
.eq("gender",1)
.gt("age",24);
List<Employee> employees = employeeMapper.selectList(queryWrapper);
或者使用 MyBatis-Plus 的 LambdaQueryWrapper 写法:
LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper
.like(Employee::getUserName,"B")
.eq(Employee::getGender,1)
.gt(Employee::getAge,24);
List<Employee> employees = employeeMapper.selectList(queryWrapper);
Fluent-MyBatis:
EmployeeQuery query = new EmployeeQuery()
.where.lastName().like("B")
.and.gender().eq(1)
.and.age().gt(24)
.end();
List<Employee> employees = employeeMapper.listEntity(query);
查询集合函数
MyBatis-Flex:
QueryWrapper query = new QueryWrapper()
.select(
ACCOUNT.ID,
ACCOUNT.USER_NAME,
max(ACCOUNT.BIRTHDAY),
avg(ACCOUNT.SEX).as("sex_avg")
);
List<Employee> employees = employeeMapper.selectListByQuery(query);
MyBatis-Plus:
QueryWrapper<Employee> queryWrapper = new QueryWrapper<>();
queryWrapper
.select(
"id"
,"user_name"
,"max(birthday)"
,"avg(birthday) as sex_avg"
);
List<Employee> employees = employeeMapper.selectList(queryWrapper);
Fluent-MyBatis:
EmployeeQuery query = new EmployeeQuery()
.select
.id()
.userName()
.max.birthday()
.avg.sex("sex_avg")
.end()
List<Employee> employees = employeeMapper.listEntity(query);
and(...) 和 or(...)
假设我们要构建如下的 SQL 进行查询(需要在 SQL 中添加括号)。
SELECT * FROM tb_account
WHERE id >= 100
AND (sex = 1 OR sex = 2)
OR (age IN (18,19,20) AND user_name LIKE "%michael%" )
MyBatis-Flex:
QueryWrapper query = QueryWrapper.create()
.where(ACCOUNT.ID.ge(100))
.and(ACCOUNT.SEX.eq(1).or(ACCOUNT.SEX.eq(2)))
.or(ACCOUNT.AGE.in(18,19,20).and(ACCOUNT.USER_NAME.like("michael")));
MyBatis-Plus:
QueryWrapper<Employee> query = new QueryWrapper<>();
queryWrapper.ge("id",100)
.and(i->i.eq("sex",1).or(x->x.eq("sex",2)))
.or(i->i.in("age",{18,19,20}).like("user_name","michael"));
Fluent-Mybatis:
AccountQuery query = new AccountQuery()
.where.id().ge(100)
.and(
new AccountQuery().where.sex().eq(1).or(
new AccountQuery().where.sex().eq(2).end()
).end())
.or(
new AccountQuery().where.age.in(18,19,20)
.and.userName().like("michael").end()
)
.end();
多表查询 1
MyBatis-Flex:
QueryWrapper query = QueryWrapper.create()
.select().from(ACCOUNT)
.leftJoin(ARTICLE).on(ACCOUNT.ID.eq(ARTICLE.ACCOUNT_ID))
.where(ACCOUNT.AGE.ge(10));
List<Account> accounts = mapper.selectListByQuery(query);
MyBatis-Plus:
Fluent-MyBatis:
StudentQuery leftQuery = new StudentQuery("a1").selectAll()
.where.age().eq(34)
.end();
HomeAddressQuery rightQuery = new HomeAddressQuery("a2")
.where.address().like("address")
.end();
IQuery query = leftQuery
.join(rightQuery)
.on(l -> l.where.homeAddressId(), r -> r.where.id()).endJoin()
.build();
List<StudentEntity> entities = this.mapper.listEntity(query);
多表查询 2
假设查询的 SQL 如下:
SELECT a.id, a.user_name, b.id AS articleId, b.title
FROM tb_account AS a, tb_article AS b
WHERE a.id = b.account_id
MyBatis-Flex:
QueryWrapper query = new QueryWrapper()
.select(
ACCOUNT.ID
, ACCOUNT.USER_NAME
, ARTICLE.ID.as("articleId")
, ARTICLE.TITLE)
.from(ACCOUNT.as("a"), ARTICLE.as("b"))
.where(ACCOUNT.ID.eq(ARTICLE.ACCOUNT_ID));
MyBatis-Plus:
Fluent-MyBatis:
PS:也有可能是我自己不知道如何支持,而非 Fluent-MyBatis 原因,有知道的同学可以给下示例代码。
部分字段更新
假设一个实体类 Account 中,我们要更新其内容如下:
userName 为 "michael"
age 为 "18"
birthday 为 null
其他字段保持数据库原有内容不变,要求执行的 SQL 如下:
update tb_account
set user_name = "michael", age = 18, birthday = null
where id = 100
Mybatis-Flex 代码如下:
Account account = UpdateEntity.of(Account.class);
account.setId(100); //设置主键
account.setUserName("michael");
account.setAge(18);
account.setBirthday(null);
accountMapper.update(account);
Mybatis-Plus 代码如下:
UpdateWrapper<Account> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("id", 100);
updateWrapper.set("user_name", "michael");
updateWrapper.set("age", 18);
updateWrapper.set("birthday", null);
accountMapper.update(null, updateWrapper);
Fluent-Mybatis 代码如下:
AccountUpdate update = new AccountUpdate()
.update.userName().is("michael")
.age().is(18)
.birthday().is(null)
.end()
.where.id().eq(100)
.end();
accountMapper.updateBy(update);