首页 文章 精选 留言 我的

精选列表

搜索[Java],共10000篇文章
优秀的个人博客,低调大师

Netty 4.1.121.Final 发布,Java 网络应用框架

Netty 是一个异步事件驱动的网络应用框架,主要用于可维护的高性能协议服务器和客户端的快速开发。 Netty 4.1.121.Final 现已发布,由于刚发布的 4.1.120.Final 时出现了一些问题,导致使用 native transport 时需要更换 GLIBC 版本,因此项目团队进行了快速的后续更新。 一些更新要点包括: Epoll.isAvailable() 在 Ubuntu 20.04/22.04 arch amd64 上返回 false (#15073) 修复 transport-native-epoll Bundle-SymbolicNames (#15068) 发布公告:https://netty.io/news/2025/04/24/4-1-121-Final.html

优秀的个人博客,低调大师

Netty 4.1.119.Final 发布,Java 网络应用框架

Netty 是一个异步事件驱动的网络应用框架,主要用于可维护的高性能协议服务器和客户端的快速开发。Netty 4.1.119.Final 现已发布,这是一个错误修复版本。 一些更新亮点包括: 用 explicit record length check 替换 SSL 断言(#14810) 修复升级消息聚合失败时出现 NPE 的问题(#14816) SslHandler:修复使用执行器进行委托时可能出现的 NPE 问题(#14830) 在 HTTP/2 日志中持续添加channel info (#14829) 添加 QueryStringDecoder 选项以单独保留 '+'(#14850) 在可用时使用初始化的 BouncyCastle providers(#14855) 发布公告:https://netty.io/news/2025/02/26/4-1-119-Final.html

优秀的个人博客,低调大师

浅谈Java数据处理框架Magician-DataProcessing

本项目是基于本人在开发中遇到的几个问题而着手设计的。 问题一 如果我们拿到了一个集合,需要根据里面的每一条数据去做相应的业务逻辑,那么我们一般有两种做法: 迭代一条一条地处理 迭代开启多线程处理 如果数据量很少的情况下,这两者都是一个不错的办法,但如果数据量高达成千上万的时候,这两者就都不是一个好办法了,前者会消耗太多的时间,而后者会开启太多的线程. 所以在处理的时候我们虽然还是会采用多线程,但是需要花时间精力去设计,让速度既能比一条一条处理要高,又不能开启太多的线程,有时候我们还不能异步处理,需要等所有线程结束了才能往下走。 我们可以看一下Magician-DataProcessing是如何处理的 假如有一个List需要并发处理里面的元素 List<String> dataList = new ArrayList<>(); 我们可以将它分成若干组来处理,这些组会排队执行,但是每一组在执行的时候都是并发的,里面的每一个元素都会由单独的线程去处理。需要等一组处理完了,才会处理下一组。 // 只需要将他传入syncRunner方法即可 MagicianDataProcessing.getConcurrentCollectionSync() .syncRunner(dataList, data -> { // 这里可以拿到List里的元素,进行处理 // List里的元素是什么类型,这个data就是什么类型 System.out.println(data); }, 10, // 每组多少条元素 1, // 每组之间同步等待多久 TimeUnit.MINUTES // 等待的时间单位 ); 也可以让每一组单独占一个线程,组内的元素依然采用迭代的方式一条条处理。等所有组处理完了,才会进入下一步。 // 也可以用syncGroupRunner方法 MagicianDataProcessing.getConcurrentCollectionSync() .syncGroupRunner(dataList, data -> { // 这里是每一组List for(String item : data){ // 这里可以拿到List里的元素,进行处理 System.out.println(data); } }, 10, // 每组多少条元素 1, // 每组之间同步等待多久 TimeUnit.MINUTES // 等待的时间单位 ); 问题二 有时候我们会遇到这样的业务逻辑:在同一条业务线里需要做多件事,但是这些事之间没有因果关系,不需要等前一个完成再去做下一个。 面对这样的情况,我们可以采用并发的方式将这多件事一起处理掉,如果我们自己去开启线程,管理线程,设置等待,本身并没啥问题,但如果项目里这样的情况多了以后,就会出现大量冗余的代码。 所以Magician-DataProcessing将他封装了 MagicianDataProcessing.getConcurrentTaskSync() .setTimeout(1000) // 超时时间 .setTimeUnit(TimeUnit.MILLISECONDS) // 超时时间的单位 .add(() -> { // 添加一个任务 // 在这里可以写上任务的业务逻辑 }, (result, e) -> { // 此任务处理后的回调 if(result.equals(ConcurrentTaskResultEnum.FAIL)){ // 任务失败,此时e里面有详细的异常信息 } else if(result.equals(ConcurrentTaskResultEnum.SUCCESS)) { // 任务成功,此时e是空的 } }) .add(() -> { // 添加一个任务 // 在这里可以写上任务的业务逻辑 }, (result, e) -> { // 此任务处理后的回调 if(result.equals(ConcurrentTaskResultEnum.FAIL)){ // 任务失败,此时e里面有详细的异常信息 } else if(result.equals(ConcurrentTaskResultEnum.SUCCESS)) { // 任务成功,此时e是空的 } }) .start(); 问题三 当我们在使用生产者与消费者模型的时候,如果不做一些处理,那么很大概率会出现一个问题,如果生产者不管不顾的向消费者推送,而消费者的消费能力又跟不上生产速度,那么很自然的会出现消费者队列积压,造成内存问题。 这样的积压如果时间久了又有可能会引发数据时效性的问题,可能你推送给消费者的时候,这条数据需要处理,但是等到被消费的时候又不需要处理了,这样就容易出现数据错乱的问题。 如果我们加大消费者的数量,又会在一定程度上增加线程数。 Magician-DataProcessing采用的是限制生产速度的方式来解决 当生产者生产完一批数据后,会不断地监视消费者,当发现了空闲的消费者才会生产和推送下一轮数据,并且数据只会推送给这几个空闲的消费者。 我们先创建一个生产者 public class DemoProducer extends MagicianProducer { /** * 设置ID,必须全局唯一,默认是当前类的全名 * 如果采用默认值,可以不重写这个方法 * @return */ @Override public String getId() { return super.getId(); } /** * 设置producer方法是否重复执行,默认重复 * 如果采用默认值,可以不重写这个方法 * @return */ @Override public boolean getLoop() { return super.getLoop(); } /** * 设置 是否等消费者全部空闲了才继续生产下一轮数据,默认false * 如果采用默认值,可以不重写这个方法 * @return */ @Override public boolean getAllFree() { return super.getAllFree(); } /** * 当生产者启动后,会自动执行这个方法,我们可以在这个方法里生产数据,并通过publish方法发布给消费者 * * 这边举一个例子 * 假如我们需要不断地扫描某张表,根据里面的数据状态去执行一些业务逻辑 * 那么我们可以在这个方法里写一个查询的逻辑,然后将查询到数据发送给消费者 */ @Override public void producer() { // 根据上面的例子,我们可以查询这张表里符合条件的数据 List<Object> dataList = selectList(); // 然后将他推送给消费者 // 可以推送任意类型的数据 this.publish(dataList); /* * 如果你只需要执行一次,那么到此就结束了,这个生产者也可以被回收掉了 * * 但是如果你需要不断地执行上述操作,来维护这张表里的数据,这个时候你有两种做法 * 第一种:加一个while循环 * 但是这种方式有个问题,如果消费者的消费速度跟不上,那么就很容易造成消费者队列积压,出现内存问题。 * 而数据积压太久又会影响时效性,可能你推送给消费者的时候,这条数据需要处理,但是等到被消费的时候又不需要处理了,这样容易出现数据错乱的问题。 * * 第二种:等消费者把你推给他的数据消费完了,再推送下一轮,而我们就是采用的这种 * 如果你想用这种方式,那么你不需要再写其他的任何逻辑,只需要将上面提到的getLoop方法重写一下,并返回true即可 * 当你设置为true以后,生产者在推送完一轮后会不断地监视消费者,当发现了空闲的消费者才会生产和推送下一轮数据,并且数据只会推送给这几个空闲的消费者 * * 如果你想等所有消费者都空闲了以后再推送下一轮,而不是发现一个空闲的就推送一轮 * 那么你可以重写上面提到的getAllFree方法,返回true即可 */ } } 再创建一个消费者 public class DemoConsumer extends MagicianConsumer { /** * 设置ID,必须全局唯一,默认是当前类的全名 * 如果采用默认值,可以不重写这个方法 * @return */ @Override public String getId() { return super.getId(); } /** * 心跳通知,消费者每消费一个任务,都会触发一下这个方法 * 我们可以根据他触发的频率来判断这个消费者的活跃度 * * 注意!!! * 这个方法里不可以有耗时的操作,不然会将消费者阻塞的 * 如果一定要加耗时的操作,那么务必在新线程里搞 * @param id */ @Override public void pulse(String id) { new Thread(()->{ // 如果你需要在这个方法里搞一些耗时的操作,那么务必要像这样开启一个新线程 // 不然消费者会被阻塞的 }).start(); } /** * 消费频率限制,默认10毫秒,取值范围:0 - long的最大值,单位:毫秒 * * 如果任务执行的耗时小于execFrequencyLimit,则等待execFrequencyLimit毫秒后再消费下一个任务 * * 首先这是一个生产者和消费者多对多的模型结构,我们以一个生产者对多个消费者来举例 * 生产者生产的数据只有一份,但是他会推送给多个消费者 * 而我们之所以要配置多个消费者,是因为需要他们执行不同的业务逻辑 * 多个消费者执行的业务逻辑不同,也就意味着他们需要的数据大概率会不同 * * 比如消费者A需要处理男性的数据,消费者B需要处理女性的数据 * 如果生产者刚好连续推送了几批男性的数据,那么这会导致消费者B筛选不到女性数据,那么他就不会处理业务逻辑了 * 这么一来,消费者B就会无限接近空转,而空转会引起CPU占用率过大,所以必须加以限制 * * 千万不要小看这个问题,本人曾经在实战中亲测过,做不做这个限制,CPU的占有率会达到10倍的差距 * 当然了,这跟消费者的业务逻辑还是有一定关系的,具体情况具体看待 * 如果你的消费者几乎不会出现空转,那么这里可以设置为0 * */ @Override public long getExecFrequencyLimit() { return super.getExecFrequencyLimit(); } /** * 这个方法会接收到生产者推送过来的数据 * 在里面执行相应的业务逻辑即可 * @param data */ @Override public void doRunner(Object data) { // data 可以是任何类型 // 因为能给他推送数据的消费者是固定的,所以data有可能收到的类型也是固定的 // 所以我们可以在这里自己判断,然后转化即可 // 为什么不用泛型?这是为了兼容多个生产者,因为他们推送的数据类型可能会不同 } } 然后将他们添加到同一个组内 // 创建一组生产者与消费者,而这样组可以创建无限个 // 每一组的生产者都只会把数据推送给同一组的消费者 MagicianDataProcessing.getProducerAndConsumerManager() .addProducer(new DemoProducer()) // 添加一个生产者(可以添加多个) .addConsumer(new DemoConsumer()) // 添加一个消费者(可以添加多个) .start();

优秀的个人博客,低调大师

Netty 4.1.112.Final 发布,Java 网络应用框架

Netty 是一个异步事件驱动的网络应用框架,主要用于可维护的高性能协议服务器和客户端的快速开发。Netty 4.1.112.Final 现已发布,这是一个错误修复版本。 具体更新内容包括: 避免在 Netty 初始化时进行不必要的 reflective probes(#14107) 允许 fragments 之间的控制帧(#14122) 仅删除 NioServerDomainSocketChannel 的套接字文件(#14134) 当地址未解析时添加对 IPv6 brackets 的检查(#14141) 修复启用 SecurityManager 时的 ResolvConf 初始化 (#14154) 修复 ResolveWithDotSearchDomain 场景中潜在的 DNS 缓存失效问题 (#14171) 反向移植 SslContextBuilder.endpointIdentificationAlgorithm 方法(#14174) 从 finalizer object 中积极删除 PoolThreadCache 引用(#14155) 通过 fireUserEventTriggered 为 Http2MultiplexHandler 发送 Http2PriorityFrame (#14168) 修复不同 EventLoop 之间潜在的 DNS 缓存失效问题 (#14147) 拒绝带有 non SP / HTAB字符的 http 标头值(#14178) 不从 header names 中删除空格,并让验证器处理它(#14179) 如果请求行中存在 NUL,则拒绝请求(#14180) 允许没有 reason-phrase的 HTTP 响应(#14183) 解码时验证 HTTP 版本 (#14187) 使用本地传输时仅在链接本地地址上包含 scopeId (#14188) 发布公告:https://netty.io/news/2024/07/19/4-1-112-Final.html

优秀的个人博客,低调大师

Java orm 框架对比】十三,新增 qdbc 框架对比

orm框架使用性能比较 优化项 时间 2024年5月7日 添加 wood框架对比测试数据库存储和查询 测试结果容易上手快速集成,但是内部使用了大量字符串不易于编写 时间 2024年5月8日 针对mysql 配置 rewriteBatchedStatements=true 保存时间明显提高 时间:2024年5月9日 事件 新增hammer_sql_db框架对比测试,该框架上手比较简单比较灵活 测试结果hammer_sql_db 批量存储做的很优秀,但当分页获取数据量超过一万后分页查询性能开始下降 时间:2024年5月11日 事件 新增原生jdbc测试 测试结果 因为未对jdbc过分优化,从结果过上看insertBatch 存在一定优势但是不大、分页查询结果集映射单纯for循环迭代会很慢 时间:2024年5月20日 事件 优化easy-query批量新增 测试结果 优化后easy-query 批量新增数据趋于稳定 时间:2024年5月21日 事件 优化jpa数据存储、十万数据存储操作分批处理,表结构新增四十个测试字段 测试结果 优化后jpa 批量新增数据趋于稳定事件大大缩减,新增四十个字段后所有ORM框架处理时间明显增多,但不是呈现倍数增加 时间:2024年5月28日 事件 新增qdbc 框架对比 测试结果 qdbc基于spring JdbcTemplate处理存储和查询性能均有所不佳 issues 处理 #I9Q8UD 事件:大表大数据处理,在原先表结构上增加40个字段 测试结果:当表结构修改时使用原生sql需要修改(db_visitor、原生jdbc、mybatis、mybatis-flex、mybatis-mp),相反使用lambda表达式则不需要过多调整 问题: 如果表不存在hammer框架回无法启动,已经提交开发者issues 使用过程中如果字段中包含下划线那么hammer 框架必须声明字段框架否则数据无法插入影响测试结果,对应的issues已经提交 #I9QGIL 事件:easy-query 优化测试结果 #I9QDC7 事件: 新增结果导出Excel #I9P24G 优化纯jdbc测试 #I9SQ6K 优化hammer框架连接数据库检测数据库空表问题 测试方法拉取代码,配置数据库账号信息,直接启动,然后打开控制台页面通过页面点击测试 比较mybatis-plus、lazy、sqltoy、mybatis-flex、easy-query、mybatis-mp、jpa、dbvisitor、beetlsql、dream_orm、wood、hammer_sql_db、原生jdbc、qdbc 操作数据 环境: idea jdk17 spring boot 3.0.7 mysql 8.0 测试条件常规对象 orm 框架 是否支持xml 是否支持 Lambda 对比版本 编码方式 注意事项 mybatis ☑️ ☑️ 3.5.4 lambda +xml 优化 ------------------------------ sqltoy ☑️ ☑️ 5.2.98 lambda ------------------------------ lazy ✖️ ☑️ 1.2.4-JDK17-SNAPSHOT lambda ------------------------------ mybatis-flex ☑️ ☑️ 1.8.0 lambda +xml 优化 ------------------------------ easy-query ✖️ ☑️ 1.10.31 lambda ------------------------------ mybatis-mp ☑️ ☑️ 1.4.1 xml 优化 ------------------------------ jpa ☑️ ☑️ 3.0.7 ---------------------- ------------------------------ dbvisitor ☑️ ☑️ 5.4.3 xml 优化 ------------------------------ beetlsql 支持md ☑️ 3.26.0-RELEASE insert ignore into 优化 ------------------------------ dream_orm ✖️ ☑️ 1.3.0 insert ignore into (当前版本不支持) ------------------------------ wood ☑️ ☑️ 1.2.9 insert ignore into (当前版本不支持) ------------------------------ hammer_sql_db ☑️ ☑️ 0.7.0 insert ignore into (当前版本不支持) 连接的数据库中如果没有表项目无法启动 jdbc ✖️ ✖️ ---------------------- ------------------------------ qdbc ☑️ ☑️ 4.2.7 ---------------------- ------------------------------ 数据库表(含有唯一性索引s_u) CREATE TABLE `sys_user` ( `column_name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '额外字段', `create_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间', `id` bigint NOT NULL AUTO_INCREMENT COMMENT '用户ID', `is_deleted` tinyint(1) DEFAULT NULL COMMENT 'null', `password` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '密码', `scope` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'null', `status` tinyint(1) DEFAULT NULL COMMENT '状态', `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `username` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '用户名', PRIMARY KEY (`id`) USING BTREE, UNIQUE KEY `s_u` (`scope`,`username`) ) ENGINE=InnoDB AUTO_INCREMENT=9223371632070323791 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; 比较方法:增加、修改、删除、分页查询(当前项目暂时只比较批量新增和分页) 项目设计 声明 ORMRepository 接口提供对应增删改查方法 声明 ORMComparisonRepository接口 继承 ORMRepository 下游由不同ORM实现 声明 SysUserRepository 接口 继承 ORMRepository 用于循环调用不同orm实现方法执行方法测试产生测试结果 声明抽象类 SysUserRepositoryAbstractRecord 继承 ORMComparisonRepository 并且提供对应的框架执行结果存储 不同ORM框架mybatis-plus、sqltoy、Lazy、easy-query、mybatis-mp、jpa、dbvisitor、beetlsql、dream_orm、wood、hammer_sql_db、原生jdbc、qdbc 创建 ORMComparisonRepository 的实现 不同 ORM 操作数据的实现 测试条件 批量插入数据 10、100、1000、10000、100000 ,分页查询数据 10、100、1000、10000、100000 项目启动后使用浏览器打开 http://localhost:1003/sys/user/run-compare 测试条件(细节比较) 批量插入数据 1~10000,分页查询数据 1~10000 项目启动后使用浏览器打开 http://localhost:1003/sys/user/run-particulars-compare 导出测试数据为MD 项目启动后使用浏览器打开 http://localhost:1003/sys/user/export-compare-result 测试执行过程 清空需要插入表中所有数据 通过ORM框架进行数据批量新增、而后进行分页查询,记录消耗时间,输出md文档 查看结果曲线图 测试结果(结果只提供参考) MYBATIS_FLEX(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 93毫秒 55毫秒 525毫秒 3961毫秒 38358毫秒 WOOD(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 17毫秒 28毫秒 208毫秒 1320毫秒 22854毫秒 MYBATIS_MP(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 20毫秒 86毫秒 388毫秒 3323毫秒 33831毫秒 MYBATIS_PLUS(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 51毫秒 135毫秒 350毫秒 3317毫秒 33736毫秒 SQLTOY(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 39毫秒 33毫秒 581毫秒 1513毫秒 32076毫秒 QDBC(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 164毫秒 90毫秒 909毫秒 6746毫秒 71587毫秒 LAZY(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 13毫秒 29毫秒 260毫秒 1711毫秒 20745毫秒 JDBC(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 49毫秒 13毫秒 69毫秒 615毫秒 6456毫秒 DB_VISITOR(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 229毫秒 24毫秒 216毫秒 1458毫秒 17238毫秒 JPA(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 320毫秒 45毫秒 284毫秒 1902毫秒 21815毫秒 EASY_QUERY(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 110毫秒 35毫秒 429毫秒 2722毫秒 20608毫秒 HAMMER_SQL_DB(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 81毫秒 19毫秒 326毫秒 2413毫秒 24478毫秒 DREAM_ORM(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 108毫秒 25毫秒 216毫秒 2628毫秒 18042毫秒 BEETL_SQL(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 213毫秒 59毫秒 263毫秒 1904毫秒 18678毫秒 MYBATIS_FLEX(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 39毫秒 16毫秒 86毫秒 594毫秒 7753毫秒 WOOD(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 17毫秒 17毫秒 51毫秒 505毫秒 6735毫秒 MYBATIS_MP(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 35毫秒 15毫秒 72毫秒 499毫秒 7552毫秒 MYBATIS_PLUS(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 34毫秒 12毫秒 66毫秒 577毫秒 6949毫秒 SQLTOY(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 21毫秒 10毫秒 30毫秒 298毫秒 4161毫秒 QDBC(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 35毫秒 104毫秒 945毫秒 9243毫秒 96091毫秒 LAZY(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 17毫秒 16毫秒 45毫秒 389毫秒 4783毫秒 JDBC(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 4毫秒 8毫秒 52毫秒 428毫秒 5458毫秒 DB_VISITOR(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 17毫秒 18毫秒 42毫秒 455毫秒 5939毫秒 JPA(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 136毫秒 23毫秒 63毫秒 454毫秒 5402毫秒 EASY_QUERY(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 60毫秒 9毫秒 40毫秒 328毫秒 3984毫秒 HAMMER_SQL_DB(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 121毫秒 15毫秒 63毫秒 623毫秒 7410毫秒 DREAM_ORM(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 62毫秒 11毫秒 32毫秒 320毫秒 4097毫秒 BEETL_SQL(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 44毫秒 13毫秒 51毫秒 432毫秒 5670毫秒 写在最后 经过不间断时间的框架收集、学习、实验、编码、测试市面上常见的ORM框架,过程中拜读了很多作者的博文、样例,学习很多收获很多。 重新梳理下整理的框架:mybatis-plus、lazy、sqltoy、mybatis-flex、easy-query、mybatis-mp、jpa、dbvisitor、beetlsql、dream_rom、wood、hammer_sql_db、原生jdbc、qdbc 下面从一下几点出发作出总结 文档方面:学习过程中mybatis-plus、jpa、db_visitor提供的文档资料是比较全和完善,经得住市场的考验 技术方面:beetlsql、easy-query、mybatis、wood、db_visitor系列 三类框架都已经支持spring 和solon生态 其技术架构设计可以推荐大家学习 并发方面:jpa、db_visitor 还需要开发时候深度优化处理 大数据存储方面: Lazy 、原生jdbc具有一定优势 大数据查询方面:sqltoy、dream_orm、Easy_query、lazy、db_visitor 反射处理的比较优秀 小数据量下各ORM框架处理时间大体相近或者通过优化后趋于一致,重点看一万数据以后框架处理能力体现价值 以上是个人整理的观点,如果大家有不同的想法和意见可以在gitee或者个人博客留言CSDN 细节数据对比(一万以内基本相差不大) 细节数据对比,数据属于并发行测试数据,如果测试总数是一百,那么会执行一百次batchStory,一百次findPage 每次执行的条数在之前数据的基础上+1 从形成的折线图看(具体趋势看排名与测试结果) 存储性能对比: lazy、原生jdbc、mybatis-flex、mybatis-mp、mybatis-plus、dream_rom、sqltoy、beetlSql、hammer_sql_db、db_visitor、easy-query、qdbc 更适合并发性数据存储。jpa 处理耗时较长波动较大 分页查询性能对比: lazy、mybatis-flex、mybatis-mp、mybatis-plus、 dream_rom、easy-query、sqltoy、db_visitor、beetlSql 、jpa、hammer_sql_db、原生jdbc都比较稳定。qdbc性能不佳 TODO 网关人员看下另一张图个上面差不多提示图片不合规 批量保存: 一万条数据以内 原生jdbc、lazy、mybatis-flex、mybatis-mp、mybatis-plus、easy-query、sqltoy、beetlSql、jpa、db_visitor、wood、hammer_sql_db、qdbc 性能趋于一致 十万数据时,处理时间由快到慢依次是: 两万毫秒以内:原生jdbc、sqltoy、db_visitor、wood、beetl_sql、dream_rom、easy-query、lazy、hammer_sql_db、 两万毫秒以上: jpa、mybatis-plus、mybatis-mp、mybatis-flex、qdbc 分页查询: 一万条数据以内 几款ORM均保持在600毫秒内 十万数据时,处理时间由快到慢依次是: 四千毫秒以内:sqltoy、dream_rom、lazy、easy-query、beetlSql、jpa、db_visitor 四千毫秒以上:原生jdbc、mybatis-mp、mybatis-plus、wood、mybatis-flex、hammer_sql_db、qdbc 快速数据对比(大数据曲线图) 关注公众号【小吴小吴bug全无】第一时间获取动态 当前项目地址:https://gitee.com/wujiawei1207537021/spring-orm-integration-compare lazy-orm地址:https://gitee.com/wujiawei1207537021/wu-framework-parent/tree/master/wu-database-parent mybatis地址:https://gitee.com/baomidou/mybatis-plus sqltoy地址:https://gitee.com/sagacity/sagacity-sqltoy mybatis-flex地址:https://gitee.com/mybatis-flex/mybatis-flex easy-query地址:https://gitee.com/xuejm/easy-query mybatis-mp地址:https://gitee.com/mybatis-mp/mybatis-mp dbvisitor地址:https://gitee.com/zycgit/dbvisitor beetlsql地址:https://gitee.com/xiandafu/beetlsql dream-orm地址:https://gitee.com/moxiaoai/dream-orm wood地址:https://gitee.com/noear/wood hammer_sql_db地址:https://gitee.com/featherfly/hammer qdbc地址:https://gitee.com/qdbp/qdbp-jdbc

优秀的个人博客,低调大师

Java orm 框架对比】十三新增 qdbc 框架对比

orm框架使用性能比较 优化项 时间 2024年5月7日 添加 wood框架对比测试数据库存储和查询 测试结果容易上手快速集成,但是内部使用了大量字符串不易于编写 时间 2024年5月8日 针对mysql 配置 rewriteBatchedStatements=true 保存时间明显提高 时间:2024年5月9日 事件 新增hammer_sql_db框架对比测试,该框架上手比较简单比较灵活 测试结果hammer_sql_db 批量存储做的很优秀,但当分页获取数据量超过一万后分页查询性能开始下降 时间:2024年5月11日 事件 新增原生jdbc测试 测试结果 因为未对jdbc过分优化,从结果过上看insertBatch 存在一定优势但是不大、分页查询结果集映射单纯for循环迭代会很慢 时间:2024年5月20日 事件 优化easy-query批量新增 测试结果 优化后easy-query 批量新增数据趋于稳定 时间:2024年5月21日 事件 优化jpa数据存储、十万数据存储操作分批处理,表结构新增四十个测试字段 测试结果 优化后jpa 批量新增数据趋于稳定事件大大缩减,新增四十个字段后所有ORM框架处理时间明显增多,但不是呈现倍数增加 时间:2024年5月28日 事件 新增qdbc 框架对比 测试结果 qdbc基于spring JdbcTemplate处理存储和查询性能均有所不佳 issues 处理 #I9Q8UD 事件:大表大数据处理,在原先表结构上增加40个字段 测试结果:当表结构修改时使用原生sql需要修改(db_visitor、原生jdbc、mybatis、mybatis-flex、mybatis-mp),相反使用lambda表达式则不需要过多调整 问题: 如果表不存在hammer框架回无法启动,已经提交开发者issues 使用过程中如果字段中包含下划线那么hammer 框架必须声明字段框架否则数据无法插入影响测试结果,对应的issues已经提交 #I9QGIL 事件:easy-query 优化测试结果 #I9QDC7 事件: 新增结果导出Excel #I9P24G 优化纯jdbc测试 #I9SQ6K 优化hammer框架连接数据库检测数据库空表问题 测试方法拉取代码,配置数据库账号信息,直接启动,然后打开控制台页面通过页面点击测试 比较mybatis-plus、lazy、sqltoy、mybatis-flex、easy-query、mybatis-mp、jpa、dbvisitor、beetlsql、dream_orm、wood、hammer_sql_db、原生jdbc、qdbc 操作数据 环境: idea jdk17 spring boot 3.0.7 mysql 8.0 测试条件常规对象 orm 框架 是否支持xml 是否支持 Lambda 对比版本 编码方式 注意事项 mybatis ☑️ ☑️ 3.5.4 lambda +xml 优化 ------------------------------ sqltoy ☑️ ☑️ 5.2.98 lambda ------------------------------ lazy ✖️ ☑️ 1.2.4-JDK17-SNAPSHOT lambda ------------------------------ mybatis-flex ☑️ ☑️ 1.8.0 lambda +xml 优化 ------------------------------ easy-query ✖️ ☑️ 1.10.31 lambda ------------------------------ mybatis-mp ☑️ ☑️ 1.4.1 xml 优化 ------------------------------ jpa ☑️ ☑️ 3.0.7 ---------------------- ------------------------------ dbvisitor ☑️ ☑️ 5.4.3 xml 优化 ------------------------------ beetlsql 支持md ☑️ 3.26.0-RELEASE insert ignore into 优化 ------------------------------ dream_orm ✖️ ☑️ 1.3.0 insert ignore into (当前版本不支持) ------------------------------ wood ☑️ ☑️ 1.2.9 insert ignore into (当前版本不支持) ------------------------------ hammer_sql_db ☑️ ☑️ 0.7.0 insert ignore into (当前版本不支持) 连接的数据库中如果没有表项目无法启动 jdbc ✖️ ✖️ ---------------------- ------------------------------ qdbc ☑️ ☑️ 4.2.7 ---------------------- ------------------------------ 数据库表(含有唯一性索引s_u) CREATE TABLE `sys_user` ( `column_name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '额外字段', `create_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间', `id` bigint NOT NULL AUTO_INCREMENT COMMENT '用户ID', `is_deleted` tinyint(1) DEFAULT NULL COMMENT 'null', `password` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '密码', `scope` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'null', `status` tinyint(1) DEFAULT NULL COMMENT '状态', `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `username` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '用户名', PRIMARY KEY (`id`) USING BTREE, UNIQUE KEY `s_u` (`scope`,`username`) ) ENGINE=InnoDB AUTO_INCREMENT=9223371632070323791 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; 比较方法:增加、修改、删除、分页查询(当前项目暂时只比较批量新增和分页) 项目设计 声明 ORMRepository 接口提供对应增删改查方法 声明 ORMComparisonRepository接口 继承 ORMRepository 下游由不同ORM实现 声明 SysUserRepository 接口 继承 ORMRepository 用于循环调用不同orm实现方法执行方法测试产生测试结果 声明抽象类 SysUserRepositoryAbstractRecord 继承 ORMComparisonRepository 并且提供对应的框架执行结果存储 不同ORM框架mybatis-plus、sqltoy、Lazy、easy-query、mybatis-mp、jpa、dbvisitor、beetlsql、dream_orm、wood、hammer_sql_db、原生jdbc、qdbc 创建 ORMComparisonRepository 的实现 不同 ORM 操作数据的实现 测试条件 批量插入数据 10、100、1000、10000、100000 ,分页查询数据 10、100、1000、10000、100000 项目启动后使用浏览器打开 http://localhost:1003/sys/user/run-compare 测试条件(细节比较) 批量插入数据 1~10000,分页查询数据 1~10000 项目启动后使用浏览器打开 http://localhost:1003/sys/user/run-particulars-compare 导出测试数据为MD 项目启动后使用浏览器打开 http://localhost:1003/sys/user/export-compare-result 测试执行过程 清空需要插入表中所有数据 通过ORM框架进行数据批量新增、而后进行分页查询,记录消耗时间,输出md文档 查看结果曲线图 测试结果(结果只提供参考) MYBATIS_FLEX(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 93毫秒 55毫秒 525毫秒 3961毫秒 38358毫秒 WOOD(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 17毫秒 28毫秒 208毫秒 1320毫秒 22854毫秒 MYBATIS_MP(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 20毫秒 86毫秒 388毫秒 3323毫秒 33831毫秒 MYBATIS_PLUS(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 51毫秒 135毫秒 350毫秒 3317毫秒 33736毫秒 SQLTOY(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 39毫秒 33毫秒 581毫秒 1513毫秒 32076毫秒 QDBC(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 164毫秒 90毫秒 909毫秒 6746毫秒 71587毫秒 LAZY(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 13毫秒 29毫秒 260毫秒 1711毫秒 20745毫秒 JDBC(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 49毫秒 13毫秒 69毫秒 615毫秒 6456毫秒 DB_VISITOR(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 229毫秒 24毫秒 216毫秒 1458毫秒 17238毫秒 JPA(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 320毫秒 45毫秒 284毫秒 1902毫秒 21815毫秒 EASY_QUERY(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 110毫秒 35毫秒 429毫秒 2722毫秒 20608毫秒 HAMMER_SQL_DB(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 81毫秒 19毫秒 326毫秒 2413毫秒 24478毫秒 DREAM_ORM(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 108毫秒 25毫秒 216毫秒 2628毫秒 18042毫秒 BEETL_SQL(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 213毫秒 59毫秒 263毫秒 1904毫秒 18678毫秒 MYBATIS_FLEX(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 39毫秒 16毫秒 86毫秒 594毫秒 7753毫秒 WOOD(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 17毫秒 17毫秒 51毫秒 505毫秒 6735毫秒 MYBATIS_MP(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 35毫秒 15毫秒 72毫秒 499毫秒 7552毫秒 MYBATIS_PLUS(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 34毫秒 12毫秒 66毫秒 577毫秒 6949毫秒 SQLTOY(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 21毫秒 10毫秒 30毫秒 298毫秒 4161毫秒 QDBC(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 35毫秒 104毫秒 945毫秒 9243毫秒 96091毫秒 LAZY(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 17毫秒 16毫秒 45毫秒 389毫秒 4783毫秒 JDBC(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 4毫秒 8毫秒 52毫秒 428毫秒 5458毫秒 DB_VISITOR(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 17毫秒 18毫秒 42毫秒 455毫秒 5939毫秒 JPA(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 136毫秒 23毫秒 63毫秒 454毫秒 5402毫秒 EASY_QUERY(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 60毫秒 9毫秒 40毫秒 328毫秒 3984毫秒 HAMMER_SQL_DB(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 121毫秒 15毫秒 63毫秒 623毫秒 7410毫秒 DREAM_ORM(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 62毫秒 11毫秒 32毫秒 320毫秒 4097毫秒 BEETL_SQL(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 44毫秒 13毫秒 51毫秒 432毫秒 5670毫秒 写在最后 经过不间断时间的框架收集、学习、实验、编码、测试市面上常见的ORM框架,过程中拜读了很多作者的博文、样例,学习很多收获很多。 重新梳理下整理的框架:mybatis-plus、lazy、sqltoy、mybatis-flex、easy-query、mybatis-mp、jpa、dbvisitor、beetlsql、dream_rom、wood、hammer_sql_db、原生jdbc、qdbc 下面从一下几点出发作出总结 文档方面:学习过程中mybatis-plus、jpa、db_visitor提供的文档资料是比较全和完善,经得住市场的考验 技术方面:beetlsql、easy-query、mybatis、wood、db_visitor系列 三类框架都已经支持spring 和solon生态 其技术架构设计可以推荐大家学习 并发方面:jpa、db_visitor 还需要开发时候深度优化处理 大数据存储方面: Lazy 、原生jdbc具有一定优势 大数据查询方面:sqltoy、dream_orm、Easy_query、lazy、db_visitor 反射处理的比较优秀 小数据量下各ORM框架处理时间大体相近或者通过优化后趋于一致,重点看一万数据以后框架处理能力体现价值 以上是个人整理的观点,如果大家有不同的想法和意见可以在gitee或者个人博客留言CSDN 细节数据对比(一万以内基本相差不大) 细节数据对比,数据属于并发行测试数据,如果测试总数是一百,那么会执行一百次batchStory,一百次findPage 每次执行的条数在之前数据的基础上+1 从形成的折线图看(具体趋势看排名与测试结果) 存储性能对比: lazy、原生jdbc、mybatis-flex、mybatis-mp、mybatis-plus、dream_rom、sqltoy、beetlSql、hammer_sql_db、db_visitor、easy-query、qdbc 更适合并发性数据存储。jpa 处理耗时较长波动较大 分页查询性能对比: lazy、mybatis-flex、mybatis-mp、mybatis-plus、 dream_rom、easy-query、sqltoy、db_visitor、beetlSql 、jpa、hammer_sql_db、原生jdbc都比较稳定。qdbc性能不佳 TODO 网关人员看下另一张图个上面差不多提示图片不合规 批量保存: 一万条数据以内 原生jdbc、lazy、mybatis-flex、mybatis-mp、mybatis-plus、easy-query、sqltoy、beetlSql、jpa、db_visitor、wood、hammer_sql_db、qdbc 性能趋于一致 十万数据时,处理时间由快到慢依次是: 两万毫秒以内:原生jdbc、sqltoy、db_visitor、wood、beetl_sql、dream_rom、easy-query、lazy、hammer_sql_db、 两万毫秒以上: jpa、mybatis-plus、mybatis-mp、mybatis-flex、qdbc 分页查询: 一万条数据以内 几款ORM均保持在600毫秒内 十万数据时,处理时间由快到慢依次是: 四千毫秒以内:sqltoy、dream_rom、lazy、easy-query、beetlSql、jpa、db_visitor 四千毫秒以上:原生jdbc、mybatis-mp、mybatis-plus、wood、mybatis-flex、hammer_sql_db、qdbc 快速数据对比(大数据曲线图) 关注公众号【小吴小吴bug全无】第一时间获取动态 当前项目地址:https://gitee.com/wujiawei1207537021/spring-orm-integration-compare lazy-orm地址:https://gitee.com/wujiawei1207537021/wu-framework-parent/tree/master/wu-database-parent mybatis地址:https://gitee.com/baomidou/mybatis-plus sqltoy地址:https://gitee.com/sagacity/sagacity-sqltoy mybatis-flex地址:https://gitee.com/mybatis-flex/mybatis-flex easy-query地址:https://gitee.com/xuejm/easy-query mybatis-mp地址:https://gitee.com/mybatis-mp/mybatis-mp dbvisitor地址:https://gitee.com/zycgit/dbvisitor beetlsql地址:https://gitee.com/xiandafu/beetlsql dream-orm地址:https://gitee.com/moxiaoai/dream-orm wood地址:https://gitee.com/noear/wood hammer_sql_db地址:https://gitee.com/featherfly/hammer qdbc地址:https://gitee.com/qdbp/qdbp-jdbc

优秀的个人博客,低调大师

Java orm 框架比较】十一 新增 原生 jdbc 对比

迁移到(https://gitee.com/wujiawei1207537021/spring-orm-integration-compare) orm框架使用性能比较 比较mybatis-plus、lazy、sqltoy、mybatis-flex、easy-query、mybatis-mp、jpa、dbvisitor、beetlsql、dream_orm、wood、hammer_sql_db、原生jdbc 操作数据 环境: idea jdk17 spring boot 3.0.7 mysql 8.0 测试条件常规对象 orm 框架 是否支持xml 是否支持 Lambda 对比版本 编码方式 mybatis ☑️ ☑️ 3.5.4 lambda +xml 优化 sqltoy ☑️ ☑️ 5.2.98 lambda lazy ✖️ ☑️ 1.2.4-JDK17-SNAPSHOT lambda mybatis-flex ☑️ ☑️ 1.8.0 lambda +xml 优化 easy-query ✖️ ☑️ 1.10.31 lambda mybatis-mp ☑️ ☑️ 1.4.1 xml 优化 jpa ☑️ ☑️ 3.0.7 ---------------------- dbvisitor ☑️ ☑️ 5.4.1 xml 优化 beetlsql 支持md ☑️ 3.26.0-RELEASE insert ignore into 优化 dream_orm ✖️ ☑️ 1.3.0 insert ignore into (当前版本不支持) wood ☑️ ☑️ 1.2.9 insert ignore into (当前版本不支持) hammer_sql_db ☑️ ☑️ 0.7.0 insert ignore into (当前版本不支持) jdbc ✖️ ✖️ 数据库表(含有唯一性索引s_u) CREATE TABLE `sys_user` ( `column_name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '额外字段', `create_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间', `id` bigint NOT NULL AUTO_INCREMENT COMMENT '用户ID', `is_deleted` tinyint(1) DEFAULT NULL COMMENT 'null', `password` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '密码', `scope` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'null', `status` tinyint(1) DEFAULT NULL COMMENT '状态', `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `username` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '用户名', PRIMARY KEY (`id`) USING BTREE, UNIQUE KEY `s_u` (`scope`,`username`) ) ENGINE=InnoDB AUTO_INCREMENT=9223371632070323791 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; 比较方法:增加、修改、删除、分页查询(当前项目暂时只比较批量新增和分页) 项目设计 声明 ORMRepository 接口提供对应增删改查方法 声明 ORMComparisonRepository接口 继承 ORMRepository 下游由不同ORM实现 声明 SysUserRepository 接口 继承 ORMRepository 用于循环调用不同orm实现方法执行方法测试产生测试结果 声明抽象类 SysUserRepositoryAbstractRecord 继承 ORMComparisonRepository 并且提供对应的框架执行结果存储 不同ORM框架mybatis-plus、sqltoy、Lazy、easy-query、mybatis-mp、jpa、dbvisitor、beetlsql、dream_orm、wood、hammer_sql_db、原生jdbc 创建 ORMComparisonRepository 的实现 不同 ORM 操作数据的实现 测试条件 批量插入数据 10、100、1000、10000、100000 ,分页查询数据 10、100、1000、10000、100000 项目启动后使用浏览器打开 http://localhost:1003/sys/user/run-compare 测试条件(细节比较) 批量插入数据 1~10000,分页查询数据 1~10000 项目启动后使用浏览器打开 http://localhost:1003/sys/user/run-particulars-compare 导出测试数据为MD 项目启动后使用浏览器打开 http://localhost:1003/sys/user/export-compare-result 测试执行过程 清空需要插入表中所有数据 通过ORM框架进行数据批量新增、而后进行分页查询,记录消耗时间,输出md文档 查看结果曲线图 测试结果(结果只提供参考) MYBATIS_FLEX(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 94毫秒 25毫秒 133毫秒 1119毫秒 9376毫秒 WOOD(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 13毫秒 18毫秒 100毫秒 400毫秒 4305毫秒 MYBATIS_MP(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 12毫秒 24毫秒 116毫秒 1021毫秒 8646毫秒 MYBATIS_PLUS(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 43毫秒 21毫秒 195毫秒 871毫秒 8578毫秒 SQLTOY(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 34毫秒 19毫秒 122毫秒 839毫秒 6994毫秒 LAZY(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 8毫秒 16毫秒 75毫秒 530毫秒 4223毫秒 JDBC(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 12毫秒 11毫秒 68毫秒 415毫秒 3750毫秒 DB_VISITOR(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 21毫秒 14毫秒 120毫秒 404毫秒 4763毫秒 JPA(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 78毫秒 72毫秒 1162毫秒 9891毫秒 87352毫秒 EASY_QUERY(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 89毫秒 317毫秒 3192毫秒 1167毫秒 10696毫秒 HAMMER_SQL_DB(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 99毫秒 18毫秒 147毫秒 937毫秒 7454毫秒 DREAM_ORM(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 48毫秒 15毫秒 117毫秒 1059毫秒 9139毫秒 BEETL_SQL(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 155毫秒 19毫秒 132毫秒 861毫秒 8667毫秒 MYBATIS_FLEX(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 29毫秒 17毫秒 31毫秒 170毫秒 1529毫秒 WOOD(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 10毫秒 10毫秒 40毫秒 148毫秒 1691毫秒 MYBATIS_MP(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 32毫秒 24毫秒 39毫秒 173毫秒 1433毫秒 MYBATIS_PLUS(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 33毫秒 10毫秒 30毫秒 178毫秒 1639毫秒 SQLTOY(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 25毫秒 11毫秒 48毫秒 166毫秒 976毫秒 LAZY(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 5毫秒 11毫秒 25毫秒 142毫秒 1103毫秒 JDBC(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 4毫秒 6毫秒 57毫秒 329毫秒 2372毫秒 DB_VISITOR(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 10毫秒 9毫秒 15毫秒 159毫秒 1044毫秒 JPA(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 135毫秒 25毫秒 81毫秒 166毫秒 1601毫秒 EASY_QUERY(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 57毫秒 13毫秒 15毫秒 137毫秒 1516毫秒 HAMMER_SQL_DB(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 162毫秒 11毫秒 39毫秒 174毫秒 1886毫秒 DREAM_ORM(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 40毫秒 8毫秒 31毫秒 145毫秒 1213毫秒 BEETL_SQL(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 53毫秒 19毫秒 47毫秒 182毫秒 1264毫秒 写在最后 经过不间断时间的框架收集、学习、实验、编码、测试市面上常见的ORM框架,过程中拜读了很多作者的博文、样例,学习很多收获很多。 重新梳理下整理的框架:mybatis-plus、lazy、sqltoy、mybatis-flex、easy-query、mybatis-mp、jpa、dbvisitor、beetlsql、dream_rom、wood、hammer_sql_db、原生jdbc 下面从一下几点出发作出总结 文档方面:学习过程中mybatis-plus、jpa、db_visitor提供的文档资料是比较全和完善,经得住市场的考验 技术方面:beetlsql、easy-query、mybatis、wood、db_visitor系列 三类框架都已经支持spring 和solon生态 其技术架构设计可以推荐大家学习 并发方面:jpa、db_visitor 还需要开发时候深度优化处理 大数据存储方面: Lazy 、原生jdbc具有一定优势 大数据查询方面:sqltoy、dream_orm、Easy_query、lazy、db_visitor 反射处理的比较优秀 小数据量下各ORM框架处理时间大体相近或者通过优化后趋于一致,重点看一万数据以后框架处理能力体现价值 以上是个人整理的观点,如果大家有不同的想法和意见可以在gitee或者个人博客留言CSDN 细节数据对比(一万以内基本相差不大) 细节数据对比,数据属于并发行测试数据,如果测试总数是一百,那么会执行一百次batchStory,一百次findPage 每次执行的条数在之前数据的基础上+1 从形成的折线图看(具体趋势看排名与测试结果) 存储性能对比: lazy、原生jdbc、mybatis-flex、mybatis-mp、mybatis-plus、dream_rom、sqltoy、beetlSql、hammer_sql_db、db_visitor 更适合并发性数据存储。jpa、easy-query 处理耗时较长波动较大 分页查询性能对比: lazy、mybatis-flex、mybatis-mp、mybatis-plus、 dream_rom、easy-query、sqltoy、db_visitor、beetlSql 、jpa、hammer_sql_db、原生jdbc都比较稳定。 批量保存: 一万条数据以内 原生jdbc、lazy、mybatis-flex、mybatis-mp、mybatis-plus、easy-query、sqltoy、beetlSql、jpa、db_visitor、wood、hammer_sql_db 性能趋于一致 十万数据时,处理时间由快到慢依次是: 八千毫秒以内:原生jdbc、lazy、dream_rom、easy-query、hammer_sql_db、sqltoy、wood、db_visitor 八千毫秒以上: mybatis-flex、mybatis-mp、mybatis-plus、beetlSql、jpa,其中 jpa 处理时间明显起伏 分页查询: 一万条数据以内 几款ORM均保持在200毫秒内 十万数据时,处理时间由快到慢依次是: 一千毫秒以内:sqltoy、dream_rom、db_visitor、easy-query、lazy、beetlSql、mybatis-plus 一千毫秒以上:mybatis-mp、jpa、mybatis-flex、wood、hammer_sql_db、原生jdbc 快速数据对比(大数据曲线图) 优化项 时间 2024年5月7日 添加 wood框架对比测试数据库存储和查询 测试结果容易上手快速集成,但是内部使用了大量字符串不易于编写 时间 2024年5月8日 针对mysql 配置 rewriteBatchedStatements=true 保存时间明显提高 时间:2024年5月9日 事件 新增hammer_sql_db框架对比测试,该框架上手比较简单比较灵活 测试结果hammer_sql_db 批量存储做的很优秀,但当分页获取数据量超过一万后分页查询性能开始下降 时间:2024年5月11日 事件 新增原生jdbc测试 测试结果 因为未对jdbc过分优化,从结果过上看insertBatch 存在一定优势但是不大、分页查询结果集映射单纯for循环迭代会很慢 当前项目地址 lazy-orm地址 mybatis地址 sqltoy地址 mybatis-flex地址 easy-query地址 mybatis-mp地址 dbvisitor地址 beetlsql地址 dream-orm地址 wood地址 hammer_sql_db地址

优秀的个人博客,低调大师

Java orm 框架使用性能比较】八

orm框架使用性能比较 比较mybatis-plus、lazy、sqltoy、mybatis-flex、easy-query、mybatis-mp、jpa、dbvisitor、beetlsql、dream_orm操作数据 环境: idea jdk17 spring boot 3.0.7 mysql 8.0 测试条件常规对象 orm 框架 是否支持xml 是否支持 Lambda 对比版本 编码方式 mybatis ☑️ ☑️ 3.5.4 lambda +xml 优化 sqltoy ☑️ ☑️ 5.2.98 lambda lazy ✖️ ☑️ 1.2.4-JDK17-SNAPSHOT lambda mybatis-flex ☑️ ☑️ 1.8.0 lambda +xml 优化 easy-query ✖️ ☑️ 1.10.31 lambda mybatis-mp ☑️ ☑️ 1.4.1 xml 优化 jpa ☑️ ☑️ 3.0.7 ---------------------- dbvisitor ☑️ ☑️ 5.4.1 xml 优化 beetlsql 支持md ☑️ 3.26.0-RELEASE insert ignore into 优化 dream_orm ✖️ ☑️ 1.3.0 insert ignore into (当前版本不支持) 数据库表(含有唯一性索引s_u) CREATE TABLE `sys_user` ( `column_name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '额外字段', `create_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间', `id` bigint NOT NULL AUTO_INCREMENT COMMENT '用户ID', `is_deleted` tinyint(1) DEFAULT NULL COMMENT 'null', `password` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '密码', `scope` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'null', `status` tinyint(1) DEFAULT NULL COMMENT '状态', `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `username` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '用户名', PRIMARY KEY (`id`) USING BTREE, UNIQUE KEY `s_u` (`scope`,`username`) ) ENGINE=InnoDB AUTO_INCREMENT=9223371632070323791 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; 比较方法:增加、修改、删除、分页查询(当前项目暂时只比较批量新增和分页) 项目设计 声明 ORMRepository 接口提供对应增删改查方法 声明 ORMComparisonRepository接口 继承 ORMRepository 下游由不同ORM实现 声明 SysUserRepository 接口 继承 ORMRepository 用于循环调用不同orm实现方法执行方法测试产生测试结果 声明抽象类 SysUserRepositoryAbstractRecord 继承 ORMComparisonRepository 并且提供对应的框架执行结果存储 不同ORM框架mybatis-plus、sqltoy、Lazy、easy-query、mybatis-mp、jpa、dbvisitor、beetlsql、dream_orm 创建 ORMComparisonRepository 的实现 不同 ORM 操作数据的实现 测试条件 批量插入数据 10、100、1000、10000、100000 ,分页查询数据 10、100、1000、10000、100000 项目启动后使用浏览器打开 http://localhost:1003/sys/user/run-compare 测试条件(细节比较) 批量插入数据 1~10000,分页查询数据 1~10000 项目启动后使用浏览器打开 http://localhost:1003/sys/user/run-particulars-compare 测试执行过程 清空需要插入表中所有数据 通过ORM框架进行数据批量新增、而后进行分页查询,记录消耗时间,输出md文档 查看结果曲线图 测试结果(结果只提供参考) MYBATIS_FLEX(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 3毫秒 9毫秒 84毫秒 827毫秒 7199毫秒 LAZY(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 3毫秒 4毫秒 51毫秒 367毫秒 3429毫秒 MYBATIS_MP(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 2毫秒 9毫秒 77毫秒 677毫秒 7177毫秒 DB_VISITOR(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 9毫秒 24毫秒 166毫秒 1609毫秒 16990毫秒 MYBATIS_PLUS(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 9毫秒 9毫秒 131毫秒 714毫秒 7349毫秒 JPA(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 13毫秒 30毫秒 1247毫秒 9894毫秒 99568毫秒 EASY_QUERY(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 10毫秒 21毫秒 202毫秒 1574毫秒 15692毫秒 SQLTOY(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 5毫秒 17毫秒 189毫秒 1537毫秒 15918毫秒 DREAM_ORM(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 12毫秒 19毫秒 159毫秒 1543毫秒 15437毫秒 BEETL_SQL(batchStory) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 17毫秒 30毫秒 174毫秒 1719毫秒 16831毫秒 MYBATIS_FLEX(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 5毫秒 4毫秒 19毫秒 153毫秒 1388毫秒 LAZY(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 6毫秒 3毫秒 11毫秒 93毫秒 700毫秒 MYBATIS_MP(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 9毫秒 3毫秒 12毫秒 111毫秒 988毫秒 DB_VISITOR(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 4毫秒 1毫秒 8毫秒 70毫秒 782毫秒 MYBATIS_PLUS(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 9毫秒 3毫秒 25毫秒 152毫秒 1309毫秒 JPA(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 15毫秒 3毫秒 25毫秒 108毫秒 1082毫秒 EASY_QUERY(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 7毫秒 1毫秒 9毫秒 61毫秒 637毫秒 SQLTOY(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 14毫秒 5毫秒 16毫秒 80毫秒 602毫秒 DREAM_ORM(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 7毫秒 1毫秒 13毫秒 62毫秒 719毫秒 BEETL_SQL(findPage) 影响行数:10 影响行数:100 影响行数:1000 影响行数:10000 影响行数:100000 执行时间: 18毫秒 2毫秒 14毫秒 89毫秒 861毫秒 写在最后 经过将近一周时间的框架收集、学习、实验、编码、测试市面上常见的ORM框架,过程中拜读了很多作者的博文、样例,学习很多收获很多。 重新梳理下整理的框架:mybatis-plus、lazy、sqltoy、mybatis-flex、easy-query、mybatis-mp、jpa、dbvisitor、beetlsql、dream_rom 下面从一下几点出发作出总结 文档方面:学习过程中mybatis-plus、jpa 提供的文档资料是比较全和完善,经得住市场的考验 技术方面:beetlsql、easy-query、mybatis系列 三类框架都已经支持spring 和solon生态 其技术架构设计可以推荐大家学习 并发方面:jpa、db_visitor 还需要开发时候深度优化处理 大数据存储方面: Lazy 具有一定优势 大数据查询方面:sqltoy、dream_orm、Easy_query、lazy、db_visitor 反射处理的比较优秀 以上是个人整理的观点,如果大家有不同的想法和意见可以在gitee或者个人博客留言CSDN 细节数据对比(一万以内基本相差不大) 细节数据对比,数据属于并发行测试数据,如果测试总数是一百,那么会执行一百次batchStory,一百次findPage 每次执行的条数在之前数据的基础上+1 从形成的折线图看(具体趋势看排名与测试结果) 存储性能对比: lazy、mybatis-flex、mybatis-mp、mybatis-plus、easy-query、dream_rom、sqltoy、beetlSql 更适合并发性数据存储。jpa、db_visitor 处理耗时较长 分页查询性能对比: lazy、mybatis-flex、mybatis-mp、mybatis-plus、 dream_rom、easy-query、sqltoy、db_visitor、beetlSql 都比较稳定。jpa 处理时间明显起伏 批量保存: 一万条数据以内 lazy、mybatis-flex、mybatis-mp、mybatis-plus、easy-query、sqltoy、beetlSql、jpa、db_visitor 性能趋于一致 十万数据时,处理时间由快到慢依次是: 一万毫秒以内:lazy、mybatis-flex、mybatis-mp、mybatis-plus、 一万毫秒以上: easy-query、dream_rom、sqltoy、beetlSql、db_visitor、jpa,其中 db_visitor、jpa 处理时间明显起伏 分页查询: 一万条数据以内 几款ORM均保持在200毫秒内 十万数据时,处理时间由快到慢依次是: 一千毫秒以内:sqltoy、dream_rom、db_visitor、easy-query、lazy、beetlSql、mybatis-plus 一千毫秒以上:mybatis-mp、jpa、mybatis-flex 快速数据对比(大数据曲线图) 当前项目地址 lazy-orm地址 mybatis地址 sqltoy地址 mybatis-flex地址 easy-query地址 mybatis-mp地址 dbvisitor地址 beetlsql地址 dream-orm地址

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册