Mybatis-Flex的简单入门,Mybatis-Flex和其它框架对比

前言

        最近做项目,项目组必须要用Mybatis-Flex,然后自己去学了一下,给大家进行分享。

        MyBatis-Flex 是 MyBatis 的一个增强工具,旨在简化 MyBatis 的使用并提高开发效率。它通过提供一系列的便捷方法和特性来减少重复代码的编写,使得数据库操作更加直观和高效。MyBatis-Flex 专注于提升开发者体验,尤其是在处理CRUD(创建、读取、更新、删除)操作时。

Mybatis-Flex的官网:MyBatis-Flex - MyBatis-Flex 官方网站

📌 特征

  1. 轻量:除了 MyBatis,没有任何第三方依赖、没有任何拦截器,在执行的过程中,没有任何的 Sql 解析(Parse)。 这带来了几个好处:极高的性能、极易对代码进行跟踪和调试、把控性更高。

  2. 灵活:支持 Entity 的增删改查、以及分页查询的同时,MyBatis-Flex 提供了 Db + Row 工具,可以无需实体类对数据库进行增删改查以及分页查询。 与此同时,MyBatis-Flex 内置的 QueryWrapper 可以轻易的帮助我们实现 多表查询、链接查询、子查询 等等常见的 SQL 场景。

  3. 强大:支持任意关系型数据库,还可以通过方言持续扩展,同时支持 多(复合)主键、逻辑删除、乐观锁配置、数据脱敏、数据审计、 数据填充 等等功能简单来说

简单来说,Mybatis-Flex 相比 Mybatis-Plus 等框架 速度更快、功能更多、代码更简洁~ 

 1、准备

1.1 首先准备一个数据库,我这里准备的是course表格,课程表

1.2 Spring Boot 项目初始化

此时需要创建 Spring Boot 项目,并添加 Maven 依赖;此处我通过 IDEA 使用 Spring Initializer 快速初始化一个 Spring Boot 工程。

📌 创建新项目,以下是相关参数:

📌 指定 spring boot 版本和勾选 web 依赖

1.3 添加 Maven 主要依赖

往 pom.xml 文件中添加以下依赖,由于本项目是通过 Spring Initializer 搭建,因此已存在 spring-boot-starter-web 和 spring-boot-starter-test 依赖。

      <dependency><groupId>com.mybatis-flex</groupId><artifactId>mybatis-flex-spring-boot-starter</artifactId><version>1.5.4</version></dependency>

1.4 配置数据源

在 application.properties 或 application.yml 中配置数据源:

#数据库连接配置
spring.datasource.username=root
spring.datasource.password=root
#mysql5~8 驱动不同driver-class-name     8需要增加时区的配置serverTimezone=UTC,放在url最后
#useSSL=false 安全连接
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

3 Mybatis-Flex 实践
3.1 编写实体类和 Mapper 接口
路径:src/main/java/com/yinyu/flex/pojo/User.java

📌 User 实体类

使用 @Table("sf_sourse") 设置实体类与表名的映射关系
使用 @Id(keyType = KeyType.Auto) 标识主键为自增

大家进行测试的话只需要加我画框框的地方就可以了 

 

 Mapper 接口继承 BaseMapper 接口

路径:src/main/java/com/yinyu/flex/mapper/UserMapper.java

这部分也可以使用 MyBatis-Flex 的代码生成器来生,功能非常强大的。详情进入:代码生成器章节 了解。

3.2 在主启动类添加 @MapperScan 注解

路径:src/main/java/com/yinyu/flex/MybatisFlexApplication.java

用于扫描 Mapper 文件夹:

package com.yinyu.flex;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
@MapperScan("com.yinyu.flex.mapper")
public class MybatisFlexApplication {public static void main(String[] args) {SpringApplication.run(MybatisFlexApplication.class, args);}}

就可以进行测试了

    /*** 查询课程列表** @param sfCourse 课程* @return 课程*/@Overridepublic List<SfCourse> selectSfCourseList(SfCourse sfCourse,Integer  pageNum, Integer pageSize) {// 创建 QueryWrapper 实例QueryWrapper queryWrapper = query().and(SF_COURSE.COURSE_ID.eq(sfCourse.getCourseId())).and(SF_COURSE.COURSE_CODE.eq(sfCourse.getCourseCode())).and(SF_COURSE.SEMESTER_ID.eq(sfCourse.getSemesterId())).and(SF_COURSE.COURSE_NAME.eq(sfCourse.getCourseName())).and(SF_COURSE.SUBJECT_ID.eq(sfCourse.getSubjectId()));if (pageNum != null && pageSize != null)return sfCourseMapper.paginate(pageNum, pageSize, queryWrapper).getRecords();elsereturn sfCourseMapper.selectListByQuery(queryWrapper);}

上面是我的测试案例。

2、MyBatis-FlexMyBatis-Plus:的对比 

基础查询对比​

MyBatis-Flex:

QueryWrapper query = QueryWrapper.create().where(EMPLOYEE.LAST_NAME.like(searchWord)) //条件为null时自动忽略.and(EMPLOYEE.GENDER.eq(1)).and(EMPLOYEE.AGE.gt(24));
List<Employee> employees = employeeMapper.selectListByQuery(query);

MyBatis-Plus:

QueryWrapper<Employee> queryWrapper = Wrappers.query().like(searchWord != null, "last_name", searchWord).eq("gender", 1).gt("age", 24);
List<Employee> employees = employeeMapper.selectList(queryWrapper);

或者 MyBatis-Plus 的 lambda 写法:

LambdaQueryWrapper<Employee> queryWrapper = Wrappers.<Employee>lambdaQuery().like(StringUtils.isNotEmpty(searchWord), 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(searchWord, If::notNull).and.gender().eq(1).and.age().gt(24).end();
List<Employee> employees = employeeMapper.listEntity(query);

查询集合函数​

MyBatis-Flex:

QueryWrapper query = QueryWrapper.create().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 = Wrappers.query().select("id","user_name","max(birthday)","avg(birthday) as sex_avg");
List<Employee> employees = employeeMapper.selectList(queryWrapper);

缺点:字段硬编码,容易拼错。无法使用 ide 的字段进行重构,无法使用 IDE 自动提示,发生错误不能及时发现。

Fluent-MyBatis:

EmployeeQuery query = new EmployeeQuery().select.id().userName().max.birthday().avg.sex("sex_avg").end()
List<Employee> employees = employeeMapper.listEntity(query);

缺点:编写内容不符合 sql 直觉。

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 = Wrappers.query().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"));
// or lambda
LambdaQueryWrapper<Employee> query = Wrappers.<Employee>lambdaQuery().ge(Employee::getId, 100).and(i -> i.eq(Employee::getSex, 1).or(x -> x.eq(Employee::getSex, 2))).or(i -> i.in(Employee::getAge, 18, 19, 20).like(Employee::getUserName, "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();

缺点:许多 .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);

缺点:编写内容不符合 sql 直觉。同时在编写 end() 和 endJoin() 容易忘记。

多表查询 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 代码如下(或可使用 MyBatis-Plus 的 LambdaUpdateWrapper,但性能没有 UpdateWrapper 好):

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);

三种框架对比

功能或特点MyBatis-FlexMyBatis-PlusFluent-MyBatis
对 entity 的基本增删改查
分页查询
分页查询之总量缓存
分页查询无 SQL 解析设计(更轻量,及更高性能)
多表查询: from 多张表
多表查询: left join、inner join 等等
多表查询: union,union all
单主键配置
多种 id 生成策略
支持多主键、复合主键
字段的 typeHandler 配置
除了 MyBatis,无其他第三方依赖(更轻量)
QueryWrapper 是否支持在微服务项目下进行 RPC 传输未知
逻辑删除
乐观锁
SQL 审计
数据填充
数据脱敏✔️ (收费)
字段权限✔️ (收费)
字段加密✔️ (收费)
字典回写✔️ (收费)
Db + Row
Entity 监听
多数据源支持借助其他框架或收费
多数据源是否支持 Spring 的事务管理,比如 @Transactional 和 TransactionTemplate 等
多数据源是否支持 "非Spring" 项目
多租户
动态表名
动态 Schema

最后

        选择哪一个框架应该基于项目的具体需求和技术栈的选择。如果你追求极致的性能并且可以接受较小的社区支持,那么 MyBatis-Flex 可能是一个不错的选择;而如果你更看重社区支持和丰富的插件生态,那么 MyBatis-Plus 则可能更适合你。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/34854.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

离线安装ollama到服务器

搜了很多教程不满意,弄了半天才弄好&#xff0c;这里记录下&#xff0c;方便以后的人用&#xff0c;那个在线下载太慢&#xff0c;怕不是得下载到明年。 一.从官网下在liunx版的tgz安装包 Releases ollama/ollama (github.com) 查看自己的服务器信息&#xff08;参考 https:/…

六款实用的开发工具的分享

文章目录 开发工具的分享一、nignx playground&#xff1a;模拟生成nginx示例二、Json在线可视化工具三、pycharm技巧四、web页面与服务器交互工具-gotty五、定时任务管理工具六、node版本管理工具 开发工具的分享 一、nignx playground&#xff1a;模拟生成nginx示例 https:…

Docker 安装 Yapi

Docker 安装系列 Docker已安装。 1、场景Yapi使用的MongoDB用户信息 1.1 创建自定义 Docker 网络 首先&#xff0c;创建一个自定义的 Docker 网络&#xff0c;以便 MongoDB 和 YApi 容器可以相互通信 [rootflexusx-328569 data]# docker network create yapi-networ…

【LeetCode】每日一题 2024_12_5 捕获黑皇后需要的最少移动次数(分类讨论)

前言 每天和你一起刷 LeetCode 每日一题~ LeetCode 启动&#xff01; 题目&#xff1a;捕获黑皇后需要的最少移动次数 代码与解题思路 先读题&#xff1a;题目给了三枚棋子&#xff0c;目标就是求出能在几步之内将皇后吃掉 具体的分类讨论见代码注释 核心思路&#xff1a;…

关于数据库连接数突然上升问题,如何进行排查

1、假设您有一个 Java 应用程序 myapp.jar&#xff0c;您可以使用以下命令启动它&#xff0c;并启用 JMX 远程管理&#xff1a; java -Dcom.sun.management.jmxremote \-Dcom.sun.management.jmxremote.port8888 \-Dcom.sun.management.jmxremote.rmi.port8080 \-Dcom.sun.man…

数据结构:顺序表详解

1.顺序表的概念与定义 2.顺序表的初始化与销毁 3.顺序表的头/尾部的插入与删除 4.顺序表指定位置的插入和删除 4.对顺序表中的数据的查找 5.总结 我以过客之名&#xff0c;祝你前程似锦 一.顺序表的概念与定义 1.概念&#xff1a; 顺序表是在计算机内存中以数组的形式保…

【算法】棋盘覆盖问题源代码及精简版

目录 一、题目 二、样例 三、示例代码 四、精简代码 五、总结 对于棋盘覆盖问题的解答和优化。 一、题目 输入格式&#xff1a; 第一行&#xff0c;一个整数n&#xff08;棋盘n*n&#xff0c;n确保是2的幂次&#xff0c;n<64&#xff09; 第二行&#xff0c;两个整数…

摩尔线程 国产显卡 MUSA 并行编程 学习笔记-2024/12/04

Learning Roadmap&#xff1a; Section 1: Intro to Parallel Programming & MUSA Deep Learning Ecosystem&#xff08;摩尔线程 国产显卡 MUSA 并行编程 学习笔记-2024/11/30-CSDN博客&#xff09;UbuntuDriverToolkitcondapytorchtorch_musa环境安装(2024/11/24-Ubunt…

App如何跨线上线下、跨渠道、跨终端归因分析

随着渠道分布多元化、生态割裂加剧、用户时间碎片化等趋势&#xff0c;多渠道投放已经成为不可阻挡的广告投放趋势。 但是App营销推广渠道那么多&#xff0c;既要确保广告效果好&#xff0c;又要避免广告资源浪费&#xff0c;有限的媒体预算应该分配给哪几个渠道&#xff1f;哪…

leetcode 3001. 捕获黑皇后需要的最少移动次数 中等

现有一个下标从 1 开始的 8 x 8 棋盘&#xff0c;上面有 3 枚棋子。 给你 6 个整数 a 、b 、c 、d 、e 和 f &#xff0c;其中&#xff1a; (a, b) 表示白色车的位置。(c, d) 表示白色象的位置。(e, f) 表示黑皇后的位置。 假定你只能移动白色棋子&#xff0c;返回捕获黑皇后…

Day6:生信新手笔记 — R包安装与R包使用

R包是多个函数的集合。学生信使用R语言的原因是丰富的图表和Biocductor上面的各种生信分析R包。 一、安装和加载R包 1.设置镜像 镜像网站相当于主网站的副本&#xff0c;访问主网站存在障碍时&#xff0c;访问镜像网站也可。选择国内的镜像可加快访问速度。运行这两行代码&a…

Spring源码解读

文章目录 Spring简单容器(以BeanFactory为主)Spring高级容器(以ApplicationCOntext为主)ListableBeanFactoryobtainFreshBeanFactory()获取BeanFactorySpring源码学习:一篇搞懂@Autowire和@Resource注解的区别Spring简单容器(以BeanFactory为主) Spring高级容器(以Appl…

达梦数据库客户端安装方法

达梦数据库客户端安装方法 达梦客户端下载地址 产品下载 | 达梦数据库 下载完成后以后是这样子的 dm8_20241011_x86_win_64.zip 然后解压 解压后的结果 双击iso的文件 然后选中 然后下一步 自定义安装路径然后下一步 安装 然后直接在开始这里搜DM管理工具 然后配置连接即…

【北京迅为】iTOP-4412全能版使用手册-第五十五章 字符类GPIOS

iTOP-4412全能版采用四核Cortex-A9&#xff0c;主频为1.4GHz-1.6GHz&#xff0c;配备S5M8767 电源管理&#xff0c;集成USB HUB,选用高品质板对板连接器稳定可靠&#xff0c;大厂生产&#xff0c;做工精良。接口一应俱全&#xff0c;开发更简单,搭载全网通4G、支持WIFI、蓝牙、…

LabVIEW算法执行时间评估与Windows硬件支持

在设计和实现复杂系统时&#xff0c;准确估算算法的执行时间是关键步骤&#xff0c;尤其在实时性要求较高的应用中。这一评估有助于确定是否需要依赖硬件加速来满足性能需求。首先需要对算法进行时间复杂度分析并进行实验测试&#xff0c;了解其在Windows系统中的运行表现。根据…

D614 PHP+MYSQL +失物招领系统网站的设计与现 源代码 配置 文档

失物招领系统 1.摘要2. 系统开发的背景和意义3.功能结构图4.界面展示5.源码获取 1.摘要 随着互联网的迅速发展&#xff0c;人们的生产生活方式逐渐发生改变&#xff0c;传统的失物招领也可以通过网络处理。本网站是基PHP技术的一款综合性较强的西南民族大学PHP失物招领系统。 …

【Java】Switch语句、循环语句(for、while、do...while)

Switch语句&#xff1a;针对某个表达式的值进行判断&#xff0c;从而决定执行哪一段代码 语法格式&#xff1a; switch(表达式){ case 目标值1: 执行语句1 break; case 目标值2: …

中建海龙:科技创新引领建筑业革新,铸就行业影响力

在建筑业这个古老而又充满活力的行业中&#xff0c;中建海龙科技有限公司&#xff08;以下简称“中建海龙”&#xff09;凭借其卓越的科技实力和一系列荣誉奖项&#xff0c;正逐步确立其在建筑工业化领域的领导地位&#xff0c;并对整个行业产生了深远影响。 中建海龙自成立以来…

【认证法规】安全隔离变压器

文章目录 定义反激电源变压器 定义 安全隔离变压器&#xff08;safety isolating transformer&#xff09;&#xff0c;通过至少相当于双重绝缘或加强绝缘的绝缘使输入绕组与输出绕组在电气上分开的变压器。这种变压器是为以安全特低电压向配电电路、电器或其它设备供电而设计…

引领素养教育行业,猿辅导素养课斩获“2024影响力教育品牌”奖项

近日&#xff0c;由教育界网、校长邦联合主办&#xff0c;鲸媒体、职教共创会协办的“第9届榜样教育年度盛典”评奖结果揭晓。据了解&#xff0c;此次评选共有近500家企业提交参评资料进行奖项角逐&#xff0c;历经教育界权威专家、资深教育从业者以及专业评审团队的多轮严格筛…