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替代性产品

jpa+querydsl的平替国产easy-query最好用的orm的更多相关文章

  1. jpa,querydsl

    [TOC] # jpa ## 生成通用模板 实现自定义方法有两种方法: 1. 根据衍生规则进行实现,此种情况简单:查询方法衍生规则 http://docs.spring.io/spring-data/ ...

  2. Spring Boot JPA - Querydsl

    https://lufficc.com/blog/spring-boot-jpa-querydsl

  3. jpa jpql @query 动态查询

    需求/背景 假设有一个用户表, 对应的用户实体: public class User { @Id Long id; //姓名 String name; //性别,男0女1 String sex; // ...

  4. Spring Data JPA教程, 第四部分: JPA Criteria Queries(未翻译)

    The third part of my Spring Data JPA tutorialdescribed how you can create custom queries by using qu ...

  5. Spring Data JPA Tutorial Part Nine: Conclusions(未翻译)

    This is the ninth and the last part of my Spring Data JPA tutorial. Now it is time to take a look of ...

  6. Spring Data JPA教程, 第七部分: Pagination(未翻译)

    The previous part of my Spring Data JPA tutorialdescribed how you can sort query results with Spring ...

  7. jpa实例

    ORM框架新的JPA ORM规范:1)JPA为POJO提供持久化标准规范.2)JPA的使用:Hibernate与TopLink以及OpenJpa都提供了JPA的实现.3)JPA主要技术:  A.ORM ...

  8. Spring data jpa 复杂动态查询方式总结

    一.Spring data jpa 简介 首先我并不推荐使用jpa作为ORM框架,毕竟对于负责查询的时候还是不太灵活,还是建议使用mybatis,自己写sql比较好.但是如果公司用这个就没办法了,可以 ...

  9. JPQ整合Querydsl入门篇

    # JPQ整合Querydsl入门篇  不知道你们喜不喜欢用JPA ,我本人是很喜欢 不要和我说JPA不适合复杂查询等等的,你要知道现在都是微服务,只要你服务器拆分够细表设计够合理,都是服务之间调能用 ...

  10. Spring JPA 定义查询方法

    Spring JPA 定义查询方法 翻译:Defining Query Methods ​ 存储库代理有两种方式基于方法名派生特定域的查询方式: 直接从方法名派生查询 自定义查询方式 ​ 可用选项基于 ...

随机推荐

  1. 7.13晚考试总结(NOIP模拟14)[队长快跑·影魔·抛硬币]

    樱花满地集于我心,楪舞纷飞祈愿相随 前言 终于没有令人头疼的数学了,总感觉这次考试的题目比较良心. 尤其是对于部分分的明细就非常到位(不像上一场的凭感觉给出部分分). 这就令我这种靠部分分暴力的菜鸡选 ...

  2. uniapp 复选框问题

    之前在开发中遇到过使用colorui组件库的时候,uniapp自带的复选框和colorui的样式有冲突,以至于出现复选框中的勾号一直不显示,后来发现是因为colorui的样式问题 问题的根源: 解决方 ...

  3. kettle从入门到精通 第十四课 kettle kafka 生产者和消费者

    1.本节课讲解kafka生产者和消费者两个步骤.这两个组件可以实现数据实时同步(后续课程会讲解). 2.kafka producer 步骤 1)step name:自定义名称 2)connection ...

  4. 前端使用 Konva 实现可视化设计器(14)- 折线 - 最优路径应用【代码篇】

    话接上回<前端使用 Konva 实现可视化设计器(13)- 折线 - 最优路径应用[思路篇]>,这一章继续说说相关的代码如何构思的,如何一步步构建数据模型可供 AStar 算法进行路径规划 ...

  5. Mysql性能优化(详解)

    引言 今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才需要担心的事,而这更是我们程序员需要去关注的事情.当我们去设计数据库表结构,对操 ...

  6. Spring Boot 使用 拦截器 实现 token 验证

    Spring Boot 使用 拦截器 实现 token 验证 整体思路:1.写一个工具类封装生成.校验和解析 token 的方法:2.在注册和登录时生成 token ,生成的 token 存入 red ...

  7. mysql连接超时的属性设置

    mysql连接超时的属性设置 2022-10-26 11:09:54.128 [http-nio-6788-exec-5] ERROR o.s.t.i.TransactionAspectSupport ...

  8. AWX+gitlab

    目录 AWX+gitlab 1. Awx配置 1.1 添加机构 1.2 添加团队 1.3 添加主机 1.4 测试主机连通性 2. 对接gitlab 2.1 添加凭证 2.2 添加项目 2.3 上传pl ...

  9. MoneyPrinterPlus:AI自动短视频生成工具-腾讯云配置详解

    MoneyPrinterPlus可以使用大模型自动生成短视频,其中的语音合成和语音识别部分需要借助于一些第三发云厂商的语音服务. 很多小伙伴可能不知道应该如何配置,这里给大家提供一个详细的腾讯云语音服 ...

  10. AGC044C Strange Dance

    在2020年A卷省选day2t2有类似操作trie的技巧. 题目链接 显然是建一棵三叉trie树,代表0/1/2 对这棵trie树,我们需要支持子树交换和全局加1 考虑第一个操作怎么做?直接打个懒标记 ...