• 【转存】 fluent mybatis 与Mybatis 简答介绍


    感谢:IT码徒 提供 原文请关注

     

    前言

    使用fluent mybatis也可以不用写具体的 xml 文件,通过 java api 可以构造出比较复杂的业务 sql 语句,做到代码逻辑和 sql 逻辑的合一。不再需要在 Dao 中组装查询或更新操作,或在 xml 与 mapper 中再组装参数。那对比原生 Mybatis,Mybatis Plus 或者其他框架,Fluent Mybatis提供了哪些便利呢?

    需求场景设置

    我们通过一个比较典型的业务需求来具体实现和对比下,假如有学生成绩表结构如下:

    1. create table `student_score`
    2. (
    3.     id           bigint auto_increment comment '主键ID' primary key,
    4.     student_id bigint            not null comment '学号',
    5.     gender_man tinyint default 0 not null comment '性别, 0:女; 1:男',
    6.     school_term int               null comment '学期',
    7.     subject varchar(30null comment '学科',
    8.     score int               null comment '成绩',
    9.     gmt_create datetime not null comment '记录创建时间',
    10.     gmt_modified datetime not null comment '记录最后修改时间',
    11.     is_deleted tinyint default 0 not null comment '逻辑删除标识'
    12. ) engine = InnoDB default charset=utf8;

    现在有需求:

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

    我们可以写 SQL 语句如下

    1. select school_term,
    2.        subject,
    3.        count(score) as count,
    4.        min(score) as min_score,
    5.        max(score) as max_score,
    6.        avg(score) as max_score
    7. from student_score
    8. where school_term >= 2000
    9.   and subject in ('英语''数学''语文')
    10.   and score >= 60
    11.   and is_deleted = 0
    12. group by school_term, subject
    13. having count(score) > 1
    14. order by school_term, subject;

    那上面的需求,分别用fluent mybatis, 原生mybatis和Mybatis plus来实现一番。

    三者实现对比

    使用fluent mybatis 来实现上面的功能

    图片

    我们可以看到fluent api的能力,以及 IDE 对代码的渲染效果。

    换成mybatis原生实现效果

    • 定义Mapper接口

    1. public interface MyStudentScoreMapper {
    2.     List<Map<StringObject>> summaryScore(SummaryQuery paras);
    3. }

    • 定义接口需要用到的参数实体 SummaryQuery

    1. @Data
    2. @Accessors(chain = true)
    3. public class SummaryQuery {
    4.     private Integer schoolTerm;
    5.     private List<String> subjects;
    6.     private Integer score;
    7.     private Integer minCount;
    8. }

    • 定义实现业务逻辑的mapper xml文件

    1. <select id="summaryScore" resultType="map" parameterType="cn.org.fluent.mybatis.springboot.demo.mapper.SummaryQuery">
    2.     select school_term,
    3.     subject,
    4.     count(score) as count,
    5.     min(score) as min_score,
    6.     max(score) as max_score,
    7.     avg(score) as max_score
    8.     from student_score
    9.     where school_term >= #{schoolTerm}
    10.     and subject in
    11.     <foreach collection="subjects" item="item" open="(" close=")" separator=",">
    12.         #{item}
    13.     </foreach>
    14.     and score >= #{score}
    15.     and is_deleted = 0
    16.     group by school_term, subject
    17.     having count(score) > #{minCount}
    18.     order by school_term, subject
    19. </select>

    • 实现业务接口(这里是测试类,实际应用中应该对应 Dao 类)

    1. @RunWith(SpringRunner.class)
    2. @SpringBootTest(classes = QuickStartApplication.class)
    3. public class MybatisDemo {
    4.     @Autowired
    5.     private MyStudentScoreMapper mapper;
    6.     @Test
    7.     public void mybatis_demo() {
    8.         // 构造查询参数
    9.         SummaryQuery paras = new SummaryQuery()
    10.             .setSchoolTerm(2000)
    11.             .setSubjects(Arrays.asList("英语""数学""语文"))
    12.             .setScore(60)
    13.             .setMinCount(1);
    14.         List<Map<StringObject>> summary = mapper.summaryScore(paras);
    15.         System.out.println(summary);
    16.     }
    17. }

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

    换成Mybaits原生实现效果

    mybatis plus的实现比mybatis会简单比较多,实现效果如下

    图片

    如红框圈出的,写mybatis plus实现用到了比较多字符串的硬编码(可以用 Entity 的 get lambda 方法部分代替字符串编码)。字符串的硬编码,会给开发同学造成不小的使用门槛,个人觉的主要有 2 点:

    • 字段名称的记忆和敲码困难

    • Entity 属性跟随数据库字段发生变更后的运行时错误

    其他框架,比如TkMybatis在封装和易用性上比mybatis plus要弱,就不再比较了。

    4

    生成代码编码比较

    fluent mybatis生成代码设置

    1. public class AppEntityGenerator {
    2.     static final String url = "jdbc:mysql://localhost:3306/fluent_mybatis_demo?useSSL=false&useUnicode=true&characterEncoding=utf-8";
    3.     public static void main(String[] args) {
    4.         FileGenerator.build(Abc.class);
    5.     }
    6.     @Tables(
    7.         /** 数据库连接信息 **/
    8.         url = url, username = "root", password = "password",
    9.         /** Entity类parent package路径 **/
    10.         basePack = "cn.org.fluent.mybatis.springboot.demo",
    11.         /** Entity代码源目录 **/
    12.         srcDir = "spring-boot-demo/src/main/java",
    13.         /** Dao代码源目录 **/
    14.         daoDir = "spring-boot-demo/src/main/java",
    15.         /** 如果表定义记录创建,记录修改,逻辑删除字段 **/
    16.         gmtCreated = "gmt_create", gmtModified = "gmt_modified", logicDeleted = "is_deleted",
    17.         /** 需要生成文件的表 ( 表名称:对应的Entity名称 ) **/
    18.         tables = @Table(value = {"student_score"})
    19.     )
    20.     static class Abc {
    21.     }
    22. }

     Mybatis Plus代码生成设置

    1. public class CodeGenerator {
    2.     static String dbUrl = "jdbc:mysql://localhost:3306/fluent_mybatis_demo?useSSL=false&useUnicode=true&characterEncoding=utf-8";
    3.     @Test
    4.     public void generateCode() {
    5.         GlobalConfig config = new GlobalConfig();
    6.         DataSourceConfig dataSourceConfig = new DataSourceConfig();
    7.         dataSourceConfig.setDbType(DbType.MYSQL)
    8.             .setUrl(dbUrl)
    9.             .setUsername("root")
    10.             .setPassword("password")
    11.             .setDriverName(Driver.class.getName());
    12.         StrategyConfig strategyConfig = new StrategyConfig();
    13.         strategyConfig
    14.             .setCapitalMode(true)
    15.             .setEntityLombokModel(false)
    16.             .setNaming(NamingStrategy.underline_to_camel)
    17.             .setColumnNaming(NamingStrategy.underline_to_camel)
    18.             .setEntityTableFieldAnnotationEnable(true)
    19.             .setFieldPrefix(new String[]{"test_"})
    20.             .setInclude(new String[]{"student_score"})
    21.             .setLogicDeleteFieldName("is_deleted")
    22.             .setTableFillList(Arrays.asList(
    23.                 new TableFill("gmt_create", FieldFill.INSERT),
    24.                 new TableFill("gmt_modified", FieldFill.INSERT_UPDATE)));
    25.         config
    26.             .setActiveRecord(false)
    27.             .setIdType(IdType.AUTO)
    28.             .setOutputDir(System.getProperty("user.dir") + "/src/main/java/")
    29.             .setFileOverride(true);
    30.         new AutoGenerator().setGlobalConfig(config)
    31.             .setDataSource(dataSourceConfig)
    32.             .setStrategy(strategyConfig)
    33.             .setPackageInfo(
    34.                 new PackageConfig()
    35.                     .setParent("com.mp.demo")
    36.                     .setController("controller")
    37.                     .setEntity("entity")
    38.             ).execute();
    39.     }
    40. }

    5

    FluentMybatis特性一览

    图片

    三者对比总结

    看完 3 个框架对同一个功能点的实现, 各位看官肯定会有自己的判断,笔者这里也总结了一份比较。

    图片

    好了,今天就介绍到这里,这里只是简单的对比三个ORM框架的区别,如果有对 Fluent Mybatis 感兴趣的小伙伴,可以去阅读官方源码,发现更多新大陆哦!

  • 相关阅读:
    2023第二届中国能源管理&碳中和国际峰会
    DASCTF X GFCTF 2022十月挑战赛
    架构师幻想之路-从负数到零-2
    HashMap、HashTable和ConcurrentHashMap之间的区别
    Acwing:730. 机器人跳跃问题(二分法)
    2021-06-09 51单片机:两个独立按键控制一个led,k1按下松开led闪烁三次,k2按下LED闪烁五次
    智慧城市物联网建设:提升城市管理效率与居民生活品质
    现代C++学习指南-方向篇
    大数据Apache Druid(四):使用Imply进行Druid集群搭建
    【LAMMPS学习】八、基础知识(4.5)TIP5P水模型
  • 原文地址:https://blog.csdn.net/qq_18237141/article/details/133377070