乐趣区

关于java:Fluent-Mybatis-原生Mybatis-Mybatis-Plus三者功能对比

应用 fluent mybatis 能够不必写具体的 xml 文件,通过 java api 能够结构出比较复杂的业务 sql 语句,做到代码逻辑和 sql 逻辑的合一。不再须要在 Dao 中组装查问或更新操作,在 xml 或 mapper 中再组装参数。那比照原生 Mybatis, Mybatis Plus 或者其余框架,FluentMybatis 提供了哪些便当呢?

需要场景设置

咱们通过一个比拟典型的业务需要来具体实现和比照下,如果有学生成绩表构造如下:

create table `student_score`
(
    id           bigint auto_increment comment '主键 ID' primary key,
    student_id   bigint            not null comment '学号',
    gender_man   tinyint default 0 not null comment '性别, 0: 女; 1: 男',
    school_term  int               null comment '学期',
    subject      varchar(30)       null comment '学科',
    score        int               null comment '问题',
    gmt_create   datetime          not null comment '记录创立工夫',
    gmt_modified datetime          not null comment '记录最初批改工夫',
    is_deleted   tinyint default 0 not null comment '逻辑删除标识'
) engine = InnoDB default charset=utf8;

当初有需要:

统计 2000 年三门学科 (‘ 英语 ’, ‘ 数学 ’, ‘ 语文 ’) 及格分数按学期, 学科统计最低分,最高分和平均分, 且样本数须要大于 1 条, 统计后果按学期和学科排序

咱们能够写 SQL 语句如下

select school_term,
       subject,
       count(score) as count,
       min(score)   as min_score,
       max(score)   as max_score,
       avg(score)   as max_score
from student_score
where school_term >= 2000
  and subject in ('英语', '数学', '语文')
  and score >= 60
  and is_deleted = 0
group by school_term, subject
having count(score) > 1
order by school_term, subject;

那下面的需要,别离用 fluent mybatis, 原生 mybatis 和 Mybatis plus 来实现一番。

三者实现比照

应用 fluent mybatis 来实现下面的性能

咱们能够看到 fluent api 的能力,以及 IDE 对代码的渲染成果。

换成 mybatis 原生实现成果

  1. 定义 Mapper 接口
public interface MyStudentScoreMapper {List<Map<String, Object>> summaryScore(SummaryQuery paras);
}
  1. 定义接口须要用到的参数实体 SummaryQuery
@Data
@Accessors(chain = true)
public class SummaryQuery {
    private Integer schoolTerm;

    private List<String> subjects;

    private Integer score;

    private Integer minCount;
}
  1. 定义实现业务逻辑的 mapper xml 文件
<select id="summaryScore" resultType="map" parameterType="cn.org.fluent.mybatis.springboot.demo.mapper.SummaryQuery">
    select school_term,
    subject,
    count(score) as count,
    min(score) as min_score,
    max(score) as max_score,
    avg(score) as max_score
    from student_score
    where school_term >= #{schoolTerm}
    and subject in
    <foreach collection="subjects" item="item" open="(" close=")" separator=",">
        #{item}
    </foreach>
    and score >= #{score}
    and is_deleted = 0
    group by school_term, subject
    having count(score) > #{minCount}
    order by school_term, subject
</select>
  1. 实现业务接口(这里是测试类, 理论利用中应该对应 Dao 类)
@RunWith(SpringRunner.class)
@SpringBootTest(classes = QuickStartApplication.class)
public class MybatisDemo {
    @Autowired
    private MyStudentScoreMapper mapper;

    @Test
    public void mybatis_demo() {
        // 结构查问参数
        SummaryQuery paras = new SummaryQuery()
            .setSchoolTerm(2000)
            .setSubjects(Arrays.asList("英语", "数学", "语文"))
            .setScore(60)
            .setMinCount(1);

        List<Map<String, Object>> summary = mapper.summaryScore(paras);
        System.out.println(summary);
    }
}

总之,间接应用 mybatis,实现步骤还是相当的繁琐,效率太低。那换成 mybatis plus 的成果怎么呢?

换成 mybatis plus 实现成果

mybatis plus 的实现比 mybatis 会简略比拟多,实现成果如下

如红框圈出的,写 mybatis plus 实现用到了比拟多字符串的硬编码(能够用 Entity 的 get lambda 办法局部代替字符串编码)。字符串的硬编码,会给开发同学造成不小的应用门槛,集体觉的次要有 2 点:

  1. 字段名称的记忆和敲码艰难
  2. Entity 属性追随数据库字段产生变更后的运行时谬误

其余框架,比方 TkMybatis 在封装和易用性上比 mybatis plus 要弱,就不再比拟了。

生成代码编码比拟

fluent mybatis 生成代码设置

public class AppEntityGenerator {
    static final String url = "jdbc:mysql://localhost:3306/fluent_mybatis_demo?useSSL=false&useUnicode=true&characterEncoding=utf-8";

    public static void main(String[] args) {FileGenerator.build(Abc.class);
    }

    @Tables(
        /** 数据库连贯信息 **/
        url = url, username = "root", password = "password",
        /** Entity 类 parent package 门路 **/
        basePack = "cn.org.fluent.mybatis.springboot.demo",
        /** Entity 代码源目录 **/
        srcDir = "spring-boot-demo/src/main/java",
        /** Dao 代码源目录 **/
        daoDir = "spring-boot-demo/src/main/java",
        /** 如果表定义记录创立,记录批改,逻辑删除字段 **/
        gmtCreated = "gmt_create", gmtModified = "gmt_modified", logicDeleted = "is_deleted",
        /** 须要生成文件的表 (表名称: 对应的 Entity 名称) **/
        tables = @Table(value = {"student_score"})
    )
    static class Abc {}}

mybatis plus 代码生成设置

public class CodeGenerator {

    static String dbUrl = "jdbc:mysql://localhost:3306/fluent_mybatis_demo?useSSL=false&useUnicode=true&characterEncoding=utf-8";

    @Test
    public void generateCode() {GlobalConfig config = new GlobalConfig();
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setDbType(DbType.MYSQL)
            .setUrl(dbUrl)
            .setUsername("root")
            .setPassword("password")
            .setDriverName(Driver.class.getName());
        StrategyConfig strategyConfig = new StrategyConfig();
        strategyConfig
            .setCapitalMode(true)
            .setEntityLombokModel(false)
            .setNaming(NamingStrategy.underline_to_camel)
            .setColumnNaming(NamingStrategy.underline_to_camel)
            .setEntityTableFieldAnnotationEnable(true)
            .setFieldPrefix(new String[]{"test_"})
            .setInclude(new String[]{"student_score"})
            .setLogicDeleteFieldName("is_deleted")
            .setTableFillList(Arrays.asList(new TableFill("gmt_create", FieldFill.INSERT),
                new TableFill("gmt_modified", FieldFill.INSERT_UPDATE)));

        config
            .setActiveRecord(false)
            .setIdType(IdType.AUTO)
            .setOutputDir(System.getProperty("user.dir") + "/src/main/java/")
            .setFileOverride(true);

        new AutoGenerator().setGlobalConfig(config)
            .setDataSource(dataSourceConfig)
            .setStrategy(strategyConfig)
            .setPackageInfo(new PackageConfig()
                    .setParent("com.mp.demo")
                    .setController("controller")
                    .setEntity("entity")
            ).execute();}
}

FluentMybatis 个性一览

三者比照总结

看完 3 个框架对同一个性能点的实现, 各位看官必定会有本人的判断,笔者这里也总结了一份比拟。

Mybatis Plus Fluent Mybatis
代码生成 生成 Entity 生成 Entity, 再通过编译生成 Mapper, Query, Update 和 SqlProvider
Generator 易用性
和 Mybatis 的共生关系 需替换原有的 SqlSessionFactoryBean 对 Mybatis 没有任何批改, 原来怎么用还是怎么用
动静 SQL 结构形式 利用启动时, 依据 Entity 注解信息结构动静 xml 片段,注入到 Mybatis 解析器 利用编译时,依据 Entity 注解,编译生成对应办法的 SqlProvider,利用 mybatis 的 Mapper 上 @InsertProvider @SelectProvider @UpdateProvider 注解关联
动静 SQL 后果是否容易 DEBUG 跟踪 不容易 debug 容易,间接定位到 SQLProvider 办法上,设置断点即可
动静 SQL 结构 通过硬编码字段名称, 或者利用 Entity 的 get 办法的 lambda 表达式 通过编译伎俩生成对应的办法名,间接调用办法即可
字段变更后的谬误发现 通过 get 办法的 lambda 表白的能够编译发现,通过字段编码的无奈编译发现 编译时便可发现
不同字段动静 SQL 构造方法 通过接口参数形式 通过接口名称形式, FluentAPI 的编码效率更高
语法渲染特点 通过要害变量 select, update, set, and, or 能够利用 IDE 语法渲染, 可读性更高
退出移动版