【硬核】开源的高性能轻量级ORM框架

2024-08-28 23:20

本文主要是介绍【硬核】开源的高性能轻量级ORM框架,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

简介

easy-orm是一款简洁、轻量高效的数据库对象关系映射框架,它的代码编写规范基于SQL语义,学习成本低,可以快速掌握。

下图是与业界mybatis-plus框架相比。

功能mybatis-pluseasy-orm
单表CRUD
多表CRUD×
子查询x
多数据源×
预编译

easy-orm不需要做任何前置工作,不依赖于任何jar包,开箱即用,以下给出easy-orm的基本使用方式。

注册数据源

用户可以任意选择接入的连接池,以HikariCP为例,用户可以在任意地方获取到数据源。

    HikariConfig config = new HikariConfig();config.setJdbcUrl("jdbc:mysql://localhost:3306/test");config.setUsername("root");config.setPassword("xxxxxx");// easy-orm支持注册多数据源,此处注册了名为mysql的数据源,并且设置为默认数据源SqlConnectFactory.register("mysql", new HikariDataSource(config), true);

1. 查询

在实体类上添加@Table注解指定表名与数据库表相关联。

查询出所有姓张的学生,并且是18到30岁以内

List<StudentModel> studentModels = SqlExecutor.builder().selectChain()//.select() 等于 select *.select(StudentModel::getId, StudentModel::getName, StudentModel::getAge).from(StudentModel.class).where(SubUtil.like(StudentModel::getName, "张%").and().between(StudentModel::getAge, 18, 30)).list(StudentModel.class);System.out.println(studentModels);// 控制台输出
22:18:05.754 [Test worker] DEBUG com.coderevolt.sql.core.dql.DQLSqlGenerator - ==> execute sql: SELECT studentModel.id,studentModel.name,studentModel.age FROM student studentModel WHERE studentModel.name LIKE (?) AND studentModel.age BETWEEN ? AND ?
22:18:05.754 [Test worker] DEBUG com.coderevolt.sql.core.dql.DQLSqlGenerator - ==> param1=%, param2=18, param3=30
22:18:07.336 [Test worker] DEBUG com.coderevolt.sql.core.dql.DQLSqlGenerator - <==  total:2
[StudentModel{id='6', name='张三', age='26'}, StudentModel{id='7', name='张玉立', age='19'}]

2.更新

更新张三的年龄为18

boolean result = SqlExecutor.builder().updateChain().update(StudentModel.class).set(SubUtil.set(StudentModel::getAge, 18)).where(SubUtil.eq(StudentModel::getName, "张三")).exec();System.out.println("更新结果:" + result);// 控制台输出
22:26:43.453 [Test worker] DEBUG com.coderevolt.sql.core.dml.DMLSqlGenerator - ==> execute sql: UPDATE student studentModel SET studentModel.age = ? WHERE studentModel.name = (?)
22:26:43.454 [Test worker] DEBUG com.coderevolt.sql.core.dml.DMLSqlGenerator - ==> param1=18, param2=张三
更新结果:true

3.删除

删除所有年纪小于10岁的学生

 boolean result = SqlExecutor.builder().deleteChain().deleteFrom(StudentModel.class).where(SubUtil.lt(StudentModel::getAge, 10)).exec();System.out.println("执行结果: " + result);// 控制台输出
22:30:42.835 [Test worker] DEBUG com.coderevolt.sql.core.dml.DMLSqlGenerator - ==> execute sql: DELETE FROM student studentModel WHERE studentModel.age < (?)
22:30:42.836 [Test worker] DEBUG com.coderevolt.sql.core.dml.DMLSqlGenerator - ==> param1=10
执行结果: true

4.新增

新增一条学生数据


boolean result = SqlExecutor.builder().insertChain()
//                .insertInto(StudentModel.class) 等于 insert into student.insertInto(StudentModel.class, StudentModel::getName, StudentModel::getAge).values(new StudentModel("老王", 20)).exec();System.out.println("执行结果: " + result);22:43:15.585 [Test worker] DEBUG com.coderevolt.sql.core.dml.DMLSqlGenerator - ==> execute sql: INSERT INTO student(name,age) VALUES (?,?)
22:43:15.586 [Test worker] DEBUG com.coderevolt.sql.core.dml.DMLSqlGenerator - ==> param1=老王, param2=20
执行结果: true

5. 多表查询

查询学生参与的课程

List<Map<String, Object>> listMap = SqlExecutor.builder().selectChain().select(StudentModel::getName, StudentModel::getAge).select(SubjectModel::getName, "subjectName").from(StudentModel.class).innerJoin(StudentSubjectRelation.class, SubUtil.eq(StudentModel::getId, StudentSubjectRelation::getStudentId)).innerJoin(SubjectModel.class, SubUtil.eq(StudentSubjectRelation::getSubjectId, SubjectModel::getId)).listMap();System.out.println(listMap);// 控制台输出
22:52:14.212 [Test worker] DEBUG com.coderevolt.sql.core.dql.DQLSqlGenerator - ==> execute sql: SELECT studentModel.name,studentModel.age,subjectModel.name AS subjectName FROM student studentModel INNER JOIN student_subject_relation studentSubjectRelation ON studentModel.id = studentSubjectRelation.student_id INNER JOIN subject subjectModel ON studentSubjectRelation.subject_id = subjectModel.id
22:52:14.231 [Test worker] DEBUG com.coderevolt.sql.core.dql.DQLSqlGenerator - <==  total:3
[{name=张三, age=18, subjectName=语文}, {name=张三, age=18, subjectName=数学}, {name=张玉立, age=19, subjectName=数学}]

6.子查询

查询参与课程的学生

SelectSqlGenerator sqlGenerator = SqlExecutor.builder(SqlOption.builder().build()).selectChain().select(StudentModel::getName).from(StudentModel.class).where(SubUtil.in(StudentModel::getId, ctx -> {return SubUtil.subSelect().select(StudentSubjectRelation::getStudentId).from(StudentSubjectRelation.class).innerJoin(SubjectModel.class, SubUtil.eq(StudentSubjectRelation::getSubjectId, SubjectModel::getId));}));
System.out.println(sqlGenerator.listMap());// 控制台输出
22:59:06.024 [Test worker] DEBUG com.coderevolt.sql.core.dql.DQLSqlGenerator - ==> execute sql: SELECT studentModel.name FROM student studentModel WHERE studentModel.id IN (SELECT studentSubjectRelation.student_id FROM student_subject_relation studentSubjectRelation INNER JOIN subject subjectModel ON studentSubjectRelation.subject_id = subjectModel.id)
22:59:06.042 [Test worker] DEBUG com.coderevolt.sql.core.dql.DQLSqlGenerator - <==  total:2
[{name=张三}, {name=张玉立}]

其他

easy-orm同样支持批量新增和批量更新,其中批量更新可以通过@Column注解指定ID属性和更新策略,例如StudentModel对象

@Table("student")
public class StudentModel {/*** @see com.coderevolt.sql.core.dml.UpdateSqlGenerator#updateById*/@Column(type = Column.ColumnType.ID)private Long id;/*** @Column注解缺省默认行为:Column.DmlStrategy.IGNORE_NULL*/private String name;@Column(dmlStrategy = Column.DmlStrategy.IGNORE_NULL)private Integer age;/*** Column.DmlStrategy.IGNORE_NULL 忽略null值,当avatar为null时忽略更新数据库,默认行为*/@Column(dmlStrategy = Column.DmlStrategy.IGNORE_NULL)private String hobby;/*** Column.DmlStrategy.SET_NULL 不忽略null值,当avatar为null时更新数据库*/@Column(dmlStrategy = Column.DmlStrategy.SET_NULL)private String avatar;
}

项目中封装了SubUtil工具类,提供了sql便捷操作方法,用户完全可以再进行扩展。AtomicUtil类提供了事务执行的方法。

项目的整体设计架构很简洁清晰,每个sql操作都是通过SqlExecutor类创建对应的sql执行链路,在builder方法中可以设置SqlOption 类来配置本次执行,或者使用默认的配置。在这个链路中会创建一个上下文容器SqlChainContext类存放所有的信息。
子查询同样可以看作是没有执行动作(例如exec()、listMap())的执行链,执行链的上下文信息会在嵌套子查询之间传递。
在这里插入图片描述

每一个子操作都被抽象成AbstractSub类的子类,并实现apply抽象方法。
子操作可以分为三大类:compare(where、havaing、on)、order(order by)、set(update set)
在这里插入图片描述

其中apply抽象方法会接收到上层执行链的上下文信息,并返回子操作的sql语句,以SubOrder为例。

@Override
public String apply(SqlChainContext ctx) {this.sqlBuf.append(SFuncUtil.getColumn(column));if (sqlSort != null) {this.sqlBuf.append(" ").append(sqlSort.name());}return toSql();
}

jmeter性能测试参考
在这里插入图片描述

最后

在开发完这个orm后我在想,能不能无感知的join和嵌套不同的数据源,屏蔽数据源的差异,就像是操作单数据源那样简单。

github地址: https://github.com/songbiaoself/easy-orm

gitee地址: https://gitee.com/song_biao/easy-orm

联系方式: 646997146@qq.com

公众号: codeRevolt

在这里插入图片描述

这篇关于【硬核】开源的高性能轻量级ORM框架的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1116179

相关文章

LiteFlow轻量级工作流引擎使用示例详解

《LiteFlow轻量级工作流引擎使用示例详解》:本文主要介绍LiteFlow是一个灵活、简洁且轻量的工作流引擎,适合用于中小型项目和微服务架构中的流程编排,本文给大家介绍LiteFlow轻量级工... 目录1. LiteFlow 主要特点2. 工作流定义方式3. LiteFlow 流程示例4. LiteF

SpringBoot集成LiteFlow实现轻量级工作流引擎的详细过程

《SpringBoot集成LiteFlow实现轻量级工作流引擎的详细过程》LiteFlow是一款专注于逻辑驱动流程编排的轻量级框架,它以组件化方式快速构建和执行业务流程,有效解耦复杂业务逻辑,下面给大... 目录一、基础概念1.1 组件(Component)1.2 规则(Rule)1.3 上下文(Conte

C++ HTTP框架推荐(特点及优势)

《C++HTTP框架推荐(特点及优势)》:本文主要介绍C++HTTP框架推荐的相关资料,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. Crow2. Drogon3. Pistache4. cpp-httplib5. Beast (Boos

SpringBoot基础框架详解

《SpringBoot基础框架详解》SpringBoot开发目的是为了简化Spring应用的创建、运行、调试和部署等,使用SpringBoot可以不用或者只需要很少的Spring配置就可以让企业项目快... 目录SpringBoot基础 – 框架介绍1.SpringBoot介绍1.1 概述1.2 核心功能2

Nginx使用Keepalived部署web集群(高可用高性能负载均衡)实战案例

《Nginx使用Keepalived部署web集群(高可用高性能负载均衡)实战案例》本文介绍Nginx+Keepalived实现Web集群高可用负载均衡的部署与测试,涵盖架构设计、环境配置、健康检查、... 目录前言一、架构设计二、环境准备三、案例部署配置 前端 Keepalived配置 前端 Nginx

C#实现高性能Excel百万数据导出优化实战指南

《C#实现高性能Excel百万数据导出优化实战指南》在日常工作中,Excel数据导出是一个常见的需求,然而,当数据量较大时,性能和内存问题往往会成为限制导出效率的瓶颈,下面我们看看C#如何结合EPPl... 目录一、技术方案核心对比二、各方案选型建议三、性能对比数据四、核心代码实现1. MiniExcel

Spring框架中@Lazy延迟加载原理和使用详解

《Spring框架中@Lazy延迟加载原理和使用详解》:本文主要介绍Spring框架中@Lazy延迟加载原理和使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、@Lazy延迟加载原理1.延迟加载原理1.1 @Lazy三种配置方法1.2 @Component

使用Python自建轻量级的HTTP调试工具

《使用Python自建轻量级的HTTP调试工具》这篇文章主要为大家详细介绍了如何使用Python自建一个轻量级的HTTP调试工具,文中的示例代码讲解详细,感兴趣的小伙伴可以参考一下... 目录一、为什么需要自建工具二、核心功能设计三、技术选型四、分步实现五、进阶优化技巧六、使用示例七、性能对比八、扩展方向建

揭秘Python Socket网络编程的7种硬核用法

《揭秘PythonSocket网络编程的7种硬核用法》Socket不仅能做聊天室,还能干一大堆硬核操作,这篇文章就带大家看看Python网络编程的7种超实用玩法,感兴趣的小伙伴可以跟随小编一起... 目录1.端口扫描器:探测开放端口2.简易 HTTP 服务器:10 秒搭个网页3.局域网游戏:多人联机对战4.

Python Dash框架在数据可视化仪表板中的应用与实践记录

《PythonDash框架在数据可视化仪表板中的应用与实践记录》Python的PlotlyDash库提供了一种简便且强大的方式来构建和展示互动式数据仪表板,本篇文章将深入探讨如何使用Dash设计一... 目录python Dash框架在数据可视化仪表板中的应用与实践1. 什么是Plotly Dash?1.1