测试功能(功能太多了,只举了几个典型的例子):AccountSample
package com.mybatisflex.test; import com.mybatisflex.core.MybatisFlexBootstrap; import com.mybatisflex.core.query.QueryWrapper; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; import javax.sql.DataSource; import java.util.Date; import java.util.List; import static com.mybatisflex.core.query.QueryMethods.max; import static com.mybatisflex.test.table.Account2TableDef.ACCOUNT2; import static com.mybatisflex.test.table.AccountTableDef.ACCOUNT; public class AccountSample { /** * 初始化数据源 * @return */ private static MybatisFlexBootstrap buildBootstrap(){ DataSource dataSource = new EmbeddedDatabaseBuilder() .setType(EmbeddedDatabaseType.H2) .addScript("schema.sql") .addScript("data.sql") .build(); MybatisFlexBootstrap bootstrap = MybatisFlexBootstrap.getInstance() .setDataSource(dataSource) // .setLogImpl(StdOutImpl.class) //日志输出配置 .addMapper(AccountMapper.class) .start(); return bootstrap; } public static void main(String[] args) { MybatisFlexBootstrap bootstrap=buildBootstrap(); //得到mapper AccountMapper accountMapper = bootstrap.getMapper(AccountMapper.class); //查询 ID 为 1 的数据 Account account = accountMapper.selectOneById(1); System.out.println(account); //新增 1 条数据 Account newAccount = new Account(); newAccount.setUserName("李四"); newAccount.setAge(18); newAccount.setBirthday(new Date()); accountMapper.insert(newAccount); System.out.println("newAccount Id: " + newAccount.getId()); //查询全部数据 System.out.println(accountMapper.selectAll()); //基本查询 where and or QueryWrapper queryWrapper = QueryWrapper.create() .select() .where(ACCOUNT.ID.eq(2)); System.out.println(accountMapper.selectOneByQuery(queryWrapper)); //聚合函数和别名的使用 QueryWrapper query = QueryWrapper.create() .select(ACCOUNT.USER_NAME, max(ACCOUNT.BIRTHDAY).as("birthday") ).groupBy(ACCOUNT.USER_NAME); System.out.println(accountMapper.selectListByQuery(query)); //left join 表 到主表对象 QueryWrapper query2 = QueryWrapper.create() .select().from(ACCOUNT) .leftJoin(ACCOUNT2).on(ACCOUNT.ID.eq(ACCOUNT2.ID)) .where(ACCOUNT.ID.eq(1)); System.out.println(accountMapper.selectListByQuery(query2)); //join 返回值设置到新对象Account3 select tb_account.user_name,tb_account2.age from tb_account join tb_account2 on tb_account.id=tb_account2.id where tb_account.id=1 QueryWrapper query3 = QueryWrapper.create() .select(ACCOUNT.USER_NAME.as("user_name3"),ACCOUNT2.AGE.as("age3")) .from(ACCOUNT) .join(ACCOUNT2).on(ACCOUNT.ID.eq(ACCOUNT2.ID)) .where(ACCOUNT.ID.eq(1)); List<Account3> results = accountMapper.selectListByQueryAs(query3, Account3.class); System.out.println(results); //MyBatis 原生注解 xml的不举例了 也是支持的 System.out.println(accountMapper.selectById(1)); } }
还提供了在 Entity 实体类之外的数据库操作能力。使用 Db + Row 时,无需对数据库表进行映射, Row 是一个 HashMap 的子类,相当于一个通用的 Entity。以下为 Db + Row 的一些示例:DbRowSample
package com.mybatisflex.test; import com.mybatisflex.core.MybatisFlexBootstrap; import com.mybatisflex.core.row.Db; import com.mybatisflex.core.row.Row; import com.mybatisflex.core.row.RowKey; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; import javax.sql.DataSource; import java.util.Date; public class DbRowSample { public static void main(String[] args) { DataSource dataSource = new EmbeddedDatabaseBuilder() .setType(EmbeddedDatabaseType.H2) .addScript("schema.sql") .addScript("data.sql") .build(); MybatisFlexBootstrap.getInstance() .setDataSource(dataSource) // .setLogImpl(StdOutImpl.class) //日志输出配置 .start(); //查询 ID 为 1 的数据 Row row = Db.selectOneById("tb_account", "id", 1); System.out.println(row); //新增一条数据,自增 Row newRow = Row.ofKey(RowKey.AUTO) .set("user_name", "lisi") .set("age", 22) .set("birthday", new Date()); Db.insert("tb_account", newRow); System.out.println("newRow.id >>>> " + newRow.get("id")); //查询所有数据 System.out.println(Db.selectAll("tb_account")); } }
PS:有些朋友可能导入项目后,这些会报错提示不存在
那是因为MyBatis-Flex 使用了 APT(Annotation Processing Tool)技术,在项目编译的时候,会自动根据 Entity 类定义的字段帮你生成 "ACCOUNT" 类以及 Entity 对应的 Mapper 类, 执行 maven 编译命令: mvn clean package 都可以自动生成。这个原理和 lombok 一致
然后点击项目目录(注意是项目的根目录),右键 > Maven:
1、 先点击 Generate Sources and Update Folders。
2、 再点击 Reload project
上面的例子只是举的非spring下轻量得使用的方法,如果想集成到spring或者springBoot里,除了最开始的初始化数据源等不一样外,获得到mapper之后的操作都是一模一样的,反正小编能想到的常用的功能都能在官方api上找到对应用法。
思考一个问题啊,我们为啥要用他?只是他比较有新鲜感?只是提供的多了一点骚方法来实现以前需要手动写sql来解决的场景?,还不足以说动我哈哈,如果性能很牛逼呢哈哈哈,下面咱们开始着重测试一下他的性能看看吧。
Mybatis-Flex 和 Mybatis-Plus 性能对比:
使用 h2 数据库,在初始化的时候分别为 flex 和 plus 创建两个不同的数据库,但是完全一样的数据结构、数据内容和数据量(每个库 2w 条数据)。直接进行预热,之后通过打印时间戳进行对比,消耗的时间越少,性能越高(每次测试 5 轮)。
运行 TestStarter 的 main 方法。
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.mybatisflex.core.query.QueryWrapper; import flex.FlexInitializer; import flex.entity.FlexAccount; import plus.PlusInitializer; import plus.entity.PlusAccount; import static flex.entity.table.Tables.FLEX_ACCOUNT; public class TestStarter { private static final int queryCount = 1000; public static void main(String[] args) { System.out.println("---------------------初始化开始---------------------"); FlexInitializer.init(); PlusInitializer.init(); System.out.println("---------------------初始化结束---------------------"); System.out.println("---------------------预热开始---------------------"); //预热防止起跑线不一致情况 testFlexSelectOne(); testPlusSelectOneWithLambda(); testPlusSelectOne(); testFlexPaginate(); testPlusPaginate(); testFlexUpdate(); testPlusUpdate(); System.out.println("---------------------预热结束---------------------"); long timeMillis; System.out.println(); System.out.println(); System.out.println("---------------------开始测试 查询单个selectOne:---------------------"); for (int i = 0; i < 5; i++) { System.out.println("---------------"); timeMillis = System.currentTimeMillis(); testFlexSelectOne(); System.out.println(">>>>>>>testFlex-SelectOne:" + (System.currentTimeMillis() - timeMillis)); timeMillis = System.currentTimeMillis(); testPlusSelectOneWithLambda(); System.out.println(">>>>>>>testPlus-SelectOneWithLambda:" + (System.currentTimeMillis() - timeMillis)); timeMillis = System.currentTimeMillis(); testPlusSelectOne(); System.out.println(">>>>>>>testPlus-SelectOne:" + (System.currentTimeMillis() - timeMillis)); } System.out.println(); System.out.println(); System.out.println("---------------------开始测试 查询多个selectList:---------------------"); for (int i = 0; i < 5; i++) { System.out.println("---------------"); timeMillis = System.currentTimeMillis(); testFlexSelectTop10(); System.out.println(">>>>>>>testFlex-SelectTop10:" + (System.currentTimeMillis() - timeMillis)); timeMillis = System.currentTimeMillis(); testPlusSelectTop10WithLambda(); System.out.println(">>>>>>>testPlus-SelectTop10WithLambda:" + (System.currentTimeMillis() - timeMillis)); timeMillis = System.currentTimeMillis(); testPlusSelectTop10(); System.out.println(">>>>>>>testPlus-SelectTop10:" + (System.currentTimeMillis() - timeMillis)); } System.out.println(); System.out.println(); System.out.println("---------------------开始测试 查询分页paginate:---------------------"); for (int i = 0; i < 5; i++) { System.out.println("---------------"); timeMillis = System.currentTimeMillis(); testFlexPaginate(); System.out.println(">>>>>>>testFlex-Paginate:" + (System.currentTimeMillis() - timeMillis)); timeMillis = System.currentTimeMillis(); testPlusPaginate(); System.out.println(">>>>>>>testPlus-Paginate:" + (System.currentTimeMillis() - timeMillis)); } System.out.println(); System.out.println(); System.out.println("---------------------开始测试 更新update:---------------------"); for (int i = 0; i < 5; i++) { System.out.println("---------------"); timeMillis = System.currentTimeMillis(); testFlexUpdate(); System.out.println(">>>>>>>testFlex-Update:" + (System.currentTimeMillis() - timeMillis)); timeMillis = System.currentTimeMillis(); testPlusUpdate(); System.out.println(">>>>>>>testPlus-Update:" + (System.currentTimeMillis() - timeMillis)); } } private static void testFlexSelectOne() { for (int i = 0; i < queryCount; i++) { FlexInitializer.selectOne(); } } private static void testPlusSelectOneWithLambda() { for (int i = 0; i < queryCount; i++) { PlusInitializer.selectOneWithLambda(); } } private static void testPlusSelectOne() { for (int i = 0; i < queryCount; i++) { PlusInitializer.selectOne(); } } private static void testFlexSelectTop10() { for (int i = 0; i < queryCount; i++) { FlexInitializer.selectTop10(); } } private static void testPlusSelectTop10WithLambda() { for (int i = 0; i < queryCount; i++) { PlusInitializer.selectTop10WithLambda(); } } private static void testPlusSelectTop10() { for (int i = 0; i < queryCount; i++) { PlusInitializer.selectTop10(); } } private static void testFlexPaginate() { for (int i = 1; i <= queryCount; i++) { QueryWrapper queryWrapper = new QueryWrapper() .where(FLEX_ACCOUNT.ID.ge(100)); FlexInitializer.paginate(1, 10, queryWrapper); } } private static void testPlusPaginate() { for (int i = 1; i <= queryCount; i++) { LambdaQueryWrapper<PlusAccount> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.ge(PlusAccount::getId, 100); PlusInitializer.paginate(1, 10, queryWrapper); } } private static void testFlexUpdate() { for (long i = 0; i < queryCount; i++) { FlexAccount flexAccount = new FlexAccount(); flexAccount.setUserName("testInsert" + i); flexAccount.setNickname("testInsert" + i); flexAccount.addOption("key1", "value1"); flexAccount.addOption("key2", "value2"); flexAccount.addOption("key3", "value3"); flexAccount.addOption("key4", "value4"); flexAccount.addOption("key5", "value5"); QueryWrapper queryWrapper = QueryWrapper.create() .where(FLEX_ACCOUNT.ID.ge(9200)) .and(FLEX_ACCOUNT.ID.le(9300)) .and(FLEX_ACCOUNT.USER_NAME.like("admin")) .and(FLEX_ACCOUNT.NICKNAME.like("admin")); FlexInitializer.update(flexAccount, queryWrapper); } } private static void testPlusUpdate() { for (int i = 0; i < queryCount; i++) { PlusAccount plusAccount = new PlusAccount(); plusAccount.setUserName("testInsert" + i); plusAccount.setNickname("testInsert" + i); plusAccount.addOption("key1", "value1"); plusAccount.addOption("key2", "value2"); plusAccount.addOption("key3", "value3"); plusAccount.addOption("key4", "value4"); plusAccount.addOption("key5", "value5"); LambdaUpdateWrapper<PlusAccount> updateWrapper = new LambdaUpdateWrapper<>(); updateWrapper.ge(PlusAccount::getId, 9000); updateWrapper.le(PlusAccount::getId, 9100); updateWrapper.like(PlusAccount::getUserName, "admin"); updateWrapper.like(PlusAccount::getNickname, "admin"); PlusInitializer.update(plusAccount, updateWrapper); } } } ## 查询单条数据 > Mybatis-Flex 的性能大概是 Mybatis-Plus 的 5 ~ 10+ 倍。 以下是日志,需要注意的是:每台机器的每次测试的数值肯定有所不同,但是应该会维持一个大概的比例。 --------------- >>>>>>>testFlex-SelectOne:74 >>>>>>>testPlus-SelectOneWithLambda:633 >>>>>>>testPlus-SelectOne:535 --------------- >>>>>>>testFlex-SelectOne:67 >>>>>>>testPlus-SelectOneWithLambda:724 >>>>>>>testPlus-SelectOne:455 --------------- >>>>>>>testFlex-SelectOne:49 >>>>>>>testPlus-SelectOneWithLambda:472 >>>>>>>testPlus-SelectOne:1158 --------------- >>>>>>>testFlex-SelectOne:36 >>>>>>>testPlus-SelectOneWithLambda:352 >>>>>>>testPlus-SelectOne:311 --------------- >>>>>>>testFlex-SelectOne:35 >>>>>>>testPlus-SelectOneWithLambda:363 >>>>>>>testPlus-SelectOne:360 --------------- ## 查询 List 数据,限制 10 条 > Mybatis-Flex 的性能大概是 Mybatis-Plus 的 5~10 倍左右 --------------- >>>>>>>testFlex-SelectTop10:41 >>>>>>>testPlus-SelectTop10WithLambda:291 >>>>>>>testPlus-SelectTop10:299 --------------- >>>>>>>testFlex-SelectTop10:35 >>>>>>>testPlus-SelectTop10WithLambda:275 >>>>>>>testPlus-SelectTop10:262 --------------- >>>>>>>testFlex-SelectTop10:36 >>>>>>>testPlus-SelectTop10WithLambda:293 >>>>>>>testPlus-SelectTop10:284 --------------- >>>>>>>testFlex-SelectTop10:35 >>>>>>>testPlus-SelectTop10WithLambda:273 >>>>>>>testPlus-SelectTop10:263 --------------- >>>>>>>testFlex-SelectTop10:34 >>>>>>>testPlus-SelectTop10WithLambda:272 >>>>>>>testPlus-SelectTop10:269 --------------- ## 分页查询 > Mybatis-Flex 的性能大概是 Mybatis-Plus 的 5~10 倍左右 >>>>>>>testFlex-Paginate:36 >>>>>>>testPlus-Paginate:301 --------------- >>>>>>>testFlex-Paginate:38 >>>>>>>testPlus-Paginate:287 --------------- >>>>>>>testFlex-Paginate:33 >>>>>>>testPlus-Paginate:266 --------------- >>>>>>>testFlex-Paginate:32 >>>>>>>testPlus-Paginate:294 --------------- >>>>>>>testFlex-Paginate:33 >>>>>>>testPlus-Paginate:333 --------------- ## 数据更新 > Mybatis-Flex 的性能大概是 Mybatis-Plus 的 5~10+ 倍左右。 --------------- >>>>>>>testFlex-Update:33 >>>>>>>testPlus-Update:287 --------------- >>>>>>>testFlex-Update:30 >>>>>>>testPlus-Update:297 --------------- >>>>>>>testFlex-Update:24 >>>>>>>testPlus-Update:241 --------------- >>>>>>>testFlex-Update:22 >>>>>>>testPlus-Update:251 --------------- >>>>>>>testFlex-Update:25 >>>>>>>testPlus-Update:271 ---------------
测试代码放到文末了,需要的同学可以自行查看:
功能测试例子源码:
https://gitee.com/fengyamin/mybatis-flex.git
性能测试例子源码:
https://gitee.com/fengyamin/mybatis-compare.git
最后,大家想获取更多知识的,可以继续关注公众号,不定时推送。分享了这么牛逼的知识,还不请小编喝个水吗,哈哈哈,欢迎土豪直接赏赞,谢谢,您的支持就是小编最大的动力。