再見MybatisPlus,阿里推出新ORM框架!
來源:juejin.cn/post/6886019929519177735
需求場景設(shè)置
我們通過一個比較典型的業(yè)務(wù)需求來具體實現(xiàn)和對比下,假如有學(xué)生成績表結(jié)構(gòu)如下:
create table `student_score`(id bigint auto_increment comment '主鍵ID' primary key,student_id bigint not null comment '學(xué)號',gender_man tinyint default 0 not null comment '性別, 0:女; 1:男',school_term int null comment '學(xué)期',subject varchar(30) null comment '學(xué)科',score int null comment '成績',gmt_create datetime not null comment '記錄創(chuàng)建時間',gmt_modified datetime not null comment '記錄最后修改時間',is_deleted tinyint default 0 not null comment '邏輯刪除標(biāo)識') engine = InnoDB default charset=utf8;
現(xiàn)在有需求:
我們可以寫 SQL 語句如下
select school_term,subject,count(score) as count,min(score) as min_score,max(score) as max_score,avg(score) as max_scorefrom student_scorewhere school_term >= 2000and subject in ('英語', '數(shù)學(xué)', '語文')and score >= 60and is_deleted = 0group by school_term, subjecthaving count(score) > 1order by school_term, subject;
那上面的需求,分別用fluent mybatis, 原生mybatis和Mybatis plus來實現(xiàn)一番。
三者實現(xiàn)對比
使用fluent mybatis 來實現(xiàn)上面的功能
我們可以看到fluent api的能力,以及 IDE 對代碼的渲染效果。
換成mybatis原生實現(xiàn)效果
定義Mapper接口
public interface MyStudentScoreMapper {List<Map<String, Object>> summaryScore(SummaryQuery paras);}
定義接口需要用到的參數(shù)實體 SummaryQuery
(chain = true)public class SummaryQuery {private Integer schoolTerm;private List<String> subjects;private Integer score;private Integer minCount;}
定義實現(xiàn)業(yè)務(wù)邏輯的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_scorefrom student_scorewhere school_term >=and subject in<foreach collection="subjects" item="item" open="(" close=")" separator=","></foreach>and score >=and is_deleted = 0group by school_term, subjecthaving count(score) > #{minCount}order by school_term, subject</select>
實現(xiàn)業(yè)務(wù)接口(這里是測試類,實際應(yīng)用中應(yīng)該對應(yīng) Dao 類)
(SpringRunner.class)(classes = QuickStartApplication.class)public class MybatisDemo {private MyStudentScoreMapper mapper;public void mybatis_demo() {// 構(gòu)造查詢參數(shù)SummaryQuery paras = new SummaryQuery().setSchoolTerm(2000).setSubjects(Arrays.asList("英語", "數(shù)學(xué)", "語文")).setScore(60).setMinCount(1);List<Map<String, Object>> summary = mapper.summaryScore(paras);System.out.println(summary);}}
總之,直接使用 mybatis,實現(xiàn)步驟還是相當(dāng)?shù)姆爆崳侍汀D菗Q成mybatis plus的效果怎樣呢?
換成mybatis plus實現(xiàn)效果
mybatis plus的實現(xiàn)比mybatis會簡單比較多,實現(xiàn)效果如下
如紅框圈出的,寫mybatis plus實現(xiàn)用到了比較多字符串的硬編碼(可以用 Entity 的 get lambda 方法部分代替字符串編碼)。字符串的硬編碼,會給開發(fā)同學(xué)造成不小的使用門檻,個人覺的主要有 2 點:
其他框架,比如TkMybatis在封裝和易用性上比mybatis plus要弱,就不再比較了。
生成代碼編碼比較
fluent mybatis生成代碼設(shè)置
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(/** 數(shù)據(jù)庫連接信息 **/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",/** 如果表定義記錄創(chuàng)建,記錄修改,邏輯刪除字段 **/gmtCreated = "gmt_create", gmtModified = "gmt_modified", logicDeleted = "is_deleted",/** 需要生成文件的表 ( 表名稱:對應(yīng)的Entity名稱 ) **/tables = @Table(value = {"student_score"}))static class Abc {}}
mybatis plus代碼生成設(shè)置
public class CodeGenerator {static String dbUrl = "jdbc:mysql://localhost:3306/fluent_mybatis_demo?useSSL=false&useUnicode=true&characterEncoding=utf-8";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特性一覽
三者對比總結(jié)
看完 3 個框架對同一個功能點的實現(xiàn), 各位看官肯定會有自己的判斷,筆者這里也總結(jié)了一份比較。

對 Fluent Mybatis 感興趣的網(wǎng)友,支持大家去閱讀官方源碼,發(fā)現(xiàn)更多新大陸!
最后,關(guān)注公眾號互聯(lián)網(wǎng)架構(gòu)師,在后臺回復(fù):2T,可以獲取我整理和創(chuàng)作的 Java 系列教程非常齊全。
1、2019 年 9 月全國程序員工資統(tǒng)計,你是什么水平?
3、從零開始搭建創(chuàng)業(yè)公司后臺技術(shù)棧
5、37歲程序員被裁,120天沒找到工作,無奈去小公司,結(jié)果懵了...
6、滴滴業(yè)務(wù)中臺構(gòu)建實踐,首次曝光
