【Java开发】 Mybatis-Flex 01:快速入门

Mybatis 作为头部的 ORM 框架,他的增强工具可谓层出不穷,比如出名的 Mybatis-Plus 和 阿里云开源的 Fluent-MyBatis,如今出了一款 Mybatis-Flex ,相比前两款功能更为强大、性能更为强悍,不妨来了解一下。

目录

1 Mybatis-Flex 介绍

2 准备工作

2.1 数据库中创建表及插入数据

2.2 Spring Boot 项目初始化

2.3 添加 Maven 主要依赖

2.4 配置数据源

3 Mybatis-Flex 实践

3.1 编写实体类和 Mapper 接口

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

3.3 Test 测试

① 普通查询

② 链式查询

4 MyBatis-Flex/Plus 代码对比

4.1 基础查询

4.2 集合查询

4.3 and(...) 和 or(...)

4.4 多表查询

4.5 部分字段更新


1 Mybatis-Flex 介绍

MyBatis-Flex 是一个优雅的 MyBatis 增强框架,它非常轻量、同时拥有极高的性能与灵活性。

📌 特征

  • 轻量:除了 MyBatis,没有任何第三方依赖、没有任何拦截器,在执行的过程中,没有任何的 Sql 解析(Parse)。 这带来了几个好处:极高的性能、极易对代码进行跟踪和调试、把控性更高。
  • 灵活:支持 Entity 的增删改查、以及分页查询的同时,MyBatis-Flex 提供了 Db + Row 工具,可以无需实体类对数据库进行增删改查以及分页查询。 与此同时,MyBatis-Flex 内置的 QueryWrapper 可以轻易的帮助我们实现 多表查询、链接查询、子查询 等等常见的 SQL 场景。
  • 强大:支持任意关系型数据库,还可以通过方言持续扩展,同时支持 多(复合)主键、逻辑删除、乐观锁配置、数据脱敏、数据审计、 数据填充 等等功能。

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

2 准备工作

官方文档:快速开始 - MyBatis-Flex

Spring Boot + Maven + Mysql 项目做演示 👇

2.1 数据库中创建表及插入数据

首先往 Mysql 数据库中添加数据表和对应的数据,脚本如下:

CREATE TABLE IF NOT EXISTS `flex_user`
(
    `id`        INTEGER PRIMARY KEY auto_increment,
    `user_name` VARCHAR(100),
    `age`       INTEGER,
    `birthday`  DATETIME
);

INSERT INTO flex_user(id, user_name, age, birthday)
VALUES (1, '张三', 18, '2020-01-11'),
       (2, '李四', 19, '2021-03-21');

我使用的是 DBeaver 工具,执行完该语句后效果如下 👇

2.2 Spring Boot 项目初始化

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

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

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

📌 删除不需要的文件,项目如图 👇

2.3 添加 Maven 主要依赖

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

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--1.数据库驱动-->
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!-- 数据库连接池组件-->
        <dependency>
            <groupId>com.zaxxer</groupId>
            <artifactId>HikariCP</artifactId>
        </dependency>
        <!--2.lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!--3.mybatis-flex-->
        <dependency>
            <groupId>com.mybatis-flex</groupId>
            <artifactId>mybatis-flex-spring-boot-starter</artifactId>
            <version>1.5.4</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

2.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("flex_user") 设置实体类与表名的映射关系
  • 使用 @Id(keyType = KeyType.Auto) 标识主键为自增
package com.yinyu.flex.pojo;

import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.annotation.Table;
import lombok.Data;
import java.util.Date;

@Data
@Table("flex_user")
public class User {

    @Id(keyType = KeyType.Auto)
    private Long id;

    private String userName;

    private Integer age;

    private Date birthday;
}

📌 Mapper 接口继承 BaseMapper 接口

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

package com.yinyu.flex.mapper;

import com.mybatisflex.core.BaseMapper;
import com.yinyu.flex.pojo.User;
import org.springframework.stereotype.Repository;

@Repository//代表持久层
public interface UserMapper extends BaseMapper<User> {
    //所有CRUD操作都编写完成了
}

这部分也可以使用 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);
    }

}

3.3 Test 测试

路径:src/test/java/com/yinyu/flex/MybatisFlexApplicationTests.java

使用测试类进行测试~

① 普通查询

package com.yinyu.flex;

import com.yinyu.flex.mapper.UserMapper;
import com.yinyu.flex.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;

@SpringBootTest
class MybatisFlexApplicationTests {

    //继承了BaseMapper,所有的方法都来自父类,我们也可以编写自己的扩展方法!
    @Autowired
    private UserMapper userMapper;

    @Test
    void contextLoads() {
        // 查询所有的记录
        List<User> users = userMapper.selectAll();
        users.forEach(System.out::println);
    }
}

输出成功 👇,可以看到完成了查询数据表的操作,展示准确!

② 链式查询

若想使用链式查询还得需要 APT 配置,MyBatis-Flex 使用了 APT(Annotation Processing Tool)技术,在项目编译的时候,会自动根据 Entity/pojo 类定义的字段帮你生成 "USER" 类(可用于链式查询)

通过开发工具构建项目(如下图),或者执行 maven 编译命令: mvn clean package 都可以自动生成。

 正常情况下,会在 target 包下生成如下资源 👇

若导入该资源失败,可点击项目目录(注意是项目的根目录),右键 > Maven:

  1. 先点击 Generate Sources and Update Folders
  2. 再点击 Reload project

若生成该资源并导入成功,那么此时,可使用链式查询 👇

import static com.yinyu.flex.pojo.table.UserTableDef.USER;
... 

   @Test
    void testWrapper() {
        // 测试链式查询
        QueryWrapper queryWrapper = QueryWrapper.create()
                .select()
                .where(USER.AGE.eq(18));
        User account = userMapper.selectOneByQuery(queryWrapper);
        System.out.println(account);
    }
...

总的来说,MyBatis-Flex 的链式查询相比 MyBatis-Plus 多了一步配置环节,目前来看其他步骤类似。

4 MyBatis-Flex/Plus 代码对比

接下来看一下MyBatis-Flex  MyBatis-Plus 各部分功能代码的差别,Employee、Account、Article 都是实体类。

4.1 基础查询

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

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

4.2 集合查询

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 自动提示,发生错误不能及时发现,不过MyBatis-Pluslambdawrapper 也是能解决这个问题。

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

4.4 多表查询

📌 情况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:不支持

📌 情况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:不支持

4.5 部分字段更新

假设一个实体类 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);

如上,MyBatis-Flex 在代码编写来说更加灵活,编写方式更多一些,还是有些优势。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尹煜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值