首页 星云 工具 资源 星选 资讯 热门工具
:

PDF转图片 完全免费 小红书视频下载 无水印 抖音视频下载 无水印 数字星空

jpa+querydsl的平替国产easy-query最好用的orm

编程知识
2024年08月02日 07:25

jpa+querydsl的平替国产easy-query最好用的orm

一款国产最强java orm,完美支持可控强类型dsl,外加完美支持对象模型筛选拉取的orm,拥有非常智能的include(s)一对多、一对一、多对多、多对一实现的orm

地址github: https://github.com/dromara/easy-query

地址gitee: https://gitee.com/dromara/easy-query

文档地址: http://www.easy-query.com/easy-query-doc/

一款拥有高度抽象屏蔽各大数据库方言的orm,让你的换库如鱼得水非常方便,集成实现各种数据库方言的使用,让你轻松应对各种需求,并且在对象模型上让你可以省去大把时间在多对多之间来回筛选

场景1

用户和角色,角色和菜单我们都知道这是最最最基础的一个场景,其中用户和角色是多对多,角色和菜单也是多对多

往往普通orm在演示的时候只会对当前表的属性进行筛选排序等操作,但是如果遇到查询主表筛选条件是子表那么大部分orm都是很麻烦的,想写出来往往是非常的费时费力并且还不支持动态条件

  • 筛选用户
  • 条件角色包含管理员的
 List<SysUser> managers = easyEntityQuery.queryable(SysUser.class)
                .where(s -> {
                    //筛选条件为角色集合里面有角色名称叫做管理员的
                    s.roles().any(role -> {
                        role.name().eq("管理员");
                    });
                }).toList();

什么你还嫌麻烦,那么如果你只有一个条件可以对roles进行展开来断言

当且仅当一(多)对多的时候那么关联模型将是集合的时候如果希望断言是否存在集合内的单一属性条件判断可以通过flatElement展开属性直接判断

        List<SysUser> managers = easyEntityQuery.queryable(SysUser.class)
                .where(s -> {
                    //筛选条件为角色集合里面有角色名称叫做管理员的
                    s.roles().flatElement().name().eq("管理员");
                }).toList();

我们来看看具体执行的sql

-- 第1条sql数据
SELECT
    t.`id`,
    t.`company_id`,
    t.`name`,
    t.`age`,
    t.`create_time` 
FROM
    `t_user` t 
WHERE
    EXISTS (
        SELECT
            1 
        FROM
            `t_role` t1 
        WHERE
            EXISTS (
                SELECT
                    1 
                FROM
                    `t_user_role` t2 
                WHERE
                    t2.`role_id` = t1.`id` 
                    AND t2.`user_id` = t.`id` LIMIT 1
            ) 
            AND t1.`name` = '管理员' LIMIT 1
        )

如果你要执行这个sql还要动态条件那么真的非常让人绝望
有人说如何做动态条件呢

   List<SysUser> managers = easyEntityQuery.queryable(SysUser.class)
                .where(s -> {
                    //筛选条件为角色集合里面有角色名称叫做管理员的
                   if(false){
                       s.roles().any(role -> {
                           role.name().eq("管理员");
                       });
                   }
                }).toList();

是的你没看错就这么简简单单的一个条件就可以让其支持动态多对多筛选,那么如果这个条件是false那么生成的sql将是怎么样的呢

SELECT `id`,`company_id`,`name`,`age`,`create_time` FROM `t_user`

是不是被easy-query这么智能的条件处理惊讶到了,如果你需要手写那么将会是灾难何况还有逻辑删除和各种拦截器

那么我们再来看看下一个场景

场景2

用户和角色和菜单

分别是多对多 和多对多

  • 筛选用户
  • 条件是用户拥有/admin的菜单
  List<SysUser> managers = easyEntityQuery.queryable(SysUser.class)
                .where(s -> {
                    //筛选条件为角色集合里面的菜单是/admin
                    s.roles().any(role -> {
                        role.menus().any(menu->{
                            menu.route().eq("/admin");
                        });
                    });
                }).toList();

哇哦简直完美简洁,什么你觉得还是太复杂了那么我们再将其简化

      List<SysUser> managers = easyEntityQuery.queryable(SysUser.class)
                .where(s -> {
                    //筛选条件为角色集合里面的菜单是/admin
                    s.roles().flatElement().menus().any(menu->{
                        menu.route().eq("/admin");
                    });
                }).toList();


//上下两种都可以,因为我们没有对roles进行条件筛选
//所以可以直接通过两次flatElement来展开元素直接断言菜单


        List<SysUser> managers = easyEntityQuery.queryable(SysUser.class)
                .where(s -> {
                    //筛选条件为角色集合里面的菜单是/admin
                    s.roles().flatElement().menus().flatElement().route().eq("/admin");
                }).toList();

接下来我们再来看看生成的sql


-- 第1条sql数据
SELECT
    t.`id`,
    t.`company_id`,
    t.`name`,
    t.`age`,
    t.`create_time` 
FROM
    `t_user` t 
WHERE
    EXISTS (
        SELECT
            1 
        FROM
            `t_role` t1 
        WHERE
            EXISTS (
                SELECT
                    1 
                FROM
                    `t_user_role` t2 
                WHERE
                    t2.`role_id` = t1.`id` 
                    AND t2.`user_id` = t.`id` LIMIT 1
            ) 
            AND EXISTS (
                SELECT
                    1 
                FROM
                    `t_menu` t3 
                WHERE
                    EXISTS (
                        SELECT
                            1 
                        FROM
                            `t_role_menu` t4 
                        WHERE
                            t4.`menu_id` = t3.`id` 
                            AND t4.`role_id` = t1.`id` LIMIT 1
                    ) 
                    AND t3.`route` = '/admin' LIMIT 1
                ) LIMIT 1
        )

我已经麻了如果没有orm简直不敢想

场景3

  • 查询用户
  • 条件是用户拥有的角色数量不少于3个的
        List<SysUser> managers = easyEntityQuery.queryable(SysUser.class)
                .where(s -> {
                    //筛选条件为角色集合的数量大于等于3个
                    s.roles().count().ge(3L);
                }).toList();

非常符合直觉
生成的sql呢是怎么样的


-- 第1条sql数据
SELECT
    t.`id`,
    t.`company_id`,
    t.`name`,
    t.`age`,
    t.`create_time` 
FROM
    `t_user` t 
WHERE
    (
        SELECT
            COUNT(*) 
        FROM
            `t_role` t1 
        WHERE
            EXISTS (
                SELECT
                    1 
                FROM
                    `t_user_role` t2 
                WHERE
                    t2.`role_id` = t1.`id` 
                    AND t2.`user_id` = t.`id` LIMIT 1
            )
        ) >= 3

场景4

  • 查询角色
  • 条件是角色关联的用户平均年龄是15岁或者姓金的至少有2位以上
List<SysRole> roles = easyEntityQuery.queryable(SysRole.class)
                .where(role -> {
                    role.or(()->{
                        role.users().avg(u->u.age()).ge(BigDecimal.valueOf(15));
                        role.users().where(u->u.name().likeMatchLeft("金")).count().ge(2L);
                    });
                }).toList();

让我们来看看生成的sql

-- 第1条sql数据
SELECT
    t.`id`,
    t.`name`,
    t.`create_time` 
FROM
    `t_role` t 
WHERE
    (
        IFNULL((SELECT
            AVG(t1.`age`) 
        FROM
            `t_user` t1 
        WHERE
            EXISTS (SELECT
                1 
            FROM
                `t_user_role` t2 
            WHERE
                t2.`user_id` = t1.`id` 
                AND t2.`role_id` = t.`id` LIMIT 1)),0) >= '15' 
        OR (
            SELECT
                COUNT(*) 
            FROM
                `t_user` t4 
            WHERE
                EXISTS (
                    SELECT
                        1 
                    FROM
                        `t_user_role` t5 
                    WHERE
                        t5.`user_id` = t4.`id` 
                        AND t5.`role_id` = t.`id` LIMIT 1
                ) 
                AND t4.`name` LIKE '金%'
            ) >= 2
    )

不要看这个sql这么复杂这可是多对多下的查询正常人压根没办法写这种sql

最后

这边展示了非常强大的OLTP查询模式,OLAP也是非常强大可以group+join,实现from (匿名sql) 也可以join (匿名sql)

一款具有强类型OLTP+OLAP的完美解决方案,并且完美支持mybatis系列的任意架构逐步构建迁移,不会产生任何冲突,因为easy-query本身就是零依赖,并且完全免费,完全开源(包括文档!!!包括文档!!!包括文档!!!)

我相信easy-query是一款可以完完全全打动您的ORM作品,也是全java唯一一款全sql替代性产品

From:https://www.cnblogs.com/xuejiaming/p/18337742
本文地址: http://shuzixingkong.net/article/687
0评论
提交 加载更多评论
其他文章 用了组合式 (Composition) API 后代码变得更乱了,怎么办?
组合式 (Composition) API 的一大特点是“非常灵活”,但也因为非常灵活,也可能导致我们的代码变得愈发混乱,最终到达无法维护的地步。
用了组合式 (Composition) API 后代码变得更乱了,怎么办? 用了组合式 (Composition) API 后代码变得更乱了,怎么办? 用了组合式 (Composition) API 后代码变得更乱了,怎么办?
还在为找开源项目发愁么?或许这个项目能帮助你
大家好,我是晓凡。 有很多小伙伴尤其是在校大学生或者想转软件开发的小伙伴,经常会问:准备找工作了,没有项目经验怎么办呢? 这时候上网找开源项目学习,就是一个获取项目经验比较靠谱的途径。 这时候又有小伙伴问了,去哪找开源项目呢? 当然是全球最大的的同性交友网站 GitHub 上找了。 这时候又有小伙伴
还在为找开源项目发愁么?或许这个项目能帮助你 还在为找开源项目发愁么?或许这个项目能帮助你 还在为找开源项目发愁么?或许这个项目能帮助你
产品、开发、测试人手一份:升级上线检查清单大全
在软件开发过程中,尤其是在准备将新功能或修复后的版本上线之前,进行详尽的自测和上线前检查是至关重要的。以下是一个从多个维度综合考量的上线升级检查清单(Checklist),旨在帮助团队确保软件质量、稳定性和安全性: 1、代码质量与构建检查 代码审查已完成 所有代码变更已通过单元测试,特别是与升级相关
SLF4J2.0.x与Logback1.3.x的绑定变动还是很大的,不要乱点鸳鸯谱
开心一刻 今天跟我姐聊天 我:我喜欢上了我们公司的一个女同事,她好漂亮,我心动了,怎么办 姐:喜欢一个女孩子不能只看她的外表 我:我知道,还要看她的内在嘛 姐:你想多了,还要看看自己的外表 背景介绍 在 SpringBoot2.7 霸王硬上弓 Logback1.3 → 不甜但解渴 原理分析那部分,我
SLF4J2.0.x与Logback1.3.x的绑定变动还是很大的,不要乱点鸳鸯谱 SLF4J2.0.x与Logback1.3.x的绑定变动还是很大的,不要乱点鸳鸯谱 SLF4J2.0.x与Logback1.3.x的绑定变动还是很大的,不要乱点鸳鸯谱
数据库系列: 主流分库分表中间件介绍(图文总结)
相关文章 数据库系列:MySQL慢查询分析和性能优化 数据库系列:MySQL索引优化总结(综合版) 数据库系列:高并发下的数据字段变更 数据库系列:覆盖索引和规避回表 数据库系列:数据库高可用及无损扩容 数据库系列:使用高区分度索引列提升性能 数据库系列:前缀索引和索引长度的取舍 数据库系列:MyS
数据库系列: 主流分库分表中间件介绍(图文总结) 数据库系列: 主流分库分表中间件介绍(图文总结)
浅析前端数据埋点监控:用户行为与性能分析的桥梁
总的来说,前端埋点技术不仅是提升用户体验和产品运行效率的利器,更是实现数据驱动决策的重要工具。随着各类专业工具的出现,如腾讯有数、百度统计和微软Clarity,企业可以根据需求选择最适合的工具进行数据分析和优化,从而在竞争激烈的市场中保持领先地位。通过深入理解用户行为和性能数据,企业能够做出更明智的
浅析前端数据埋点监控:用户行为与性能分析的桥梁 浅析前端数据埋点监控:用户行为与性能分析的桥梁 浅析前端数据埋点监控:用户行为与性能分析的桥梁
.NET8 Blazor 从入门到精通:(一)关键概念
目录Blazor 的关键概念项目模板Razor 语法依赖注入注入配置HeadOutlet 组件@code 分离Blazor 调试CSS 隔离调用JavaScript 最近在学习 Blazor ,在B站上找了一个国外的课程边看边学习。嗯,原价¥1503的课程,大概200多美元,课程链接如下: B站(大
.NET8 Blazor 从入门到精通:(一)关键概念 .NET8 Blazor 从入门到精通:(一)关键概念 .NET8 Blazor 从入门到精通:(一)关键概念
Netty的源码分析和业务场景
Netty 是一个高性能、异步事件驱动的网络应用框架,它基于 Java NIO 构建,广泛应用于互联网、大数据、游戏开发、通信行业等多个领域。以下是对 Netty 的源码分析、业务场景的详细介绍: 源码概述 Netty 的核心组件:Netty 的架构设计围绕着事件驱动的核心思想,主要包括 Chann