news 2026/4/18 7:55:02

C#转java的最好利器easy-query就是efcore4j sqlsugar4j freesql4j

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C#转java的最好利器easy-query就是efcore4j sqlsugar4j freesql4j

数据库模型

image

点击查看实体代码

案例

查询用户信息和最早开户的银行卡信息

通过模型我们可以清晰的看到SysUser和BankCard是一对多的关系,eq如何实现这种一对多的数据返回呢?

使用临时对象返回

var list = easyEntityQuery.queryable(SysUser.class)

.select(user -> {

//定义最早开户的银行卡

SysBankCardProxy firstBankCard = user.bankCards().orderBy(bankCard -> bankCard.openTime().asc()).first();

return Select.DRAFT.of(

user.id(),

user.name(),

firstBankCard.code(),

firstBankCard.type(),

firstBankCard.openTime(),

firstBankCard.bank().name()

);

}).toList();

生成的sql

SELECT t.`id` AS `value1`, t.`name` AS `value2`, t3.`code` AS `value3`, t3.`type` AS `value4`, t3.`open_time` AS `value5`

, t4.`name` AS `value6`

FROM `t_sys_user` t

LEFT JOIN (

SELECT t1.`id`, t1.`uid`, t1.`code`, t1.`type`, t1.`bank_id`

, t1.`open_time`, ROW_NUMBER() OVER (PARTITION BY t1.`uid` ORDER BY t1.`open_time` ASC) AS `__row__`

FROM `t_bank_card` t1

) t3

ON t3.`uid` = t.`id`

AND t3.`__row__` = 1

INNER JOIN `t_bank` t4 ON t4.`id` = t3.`bank_id`

查询用户至少有5张储蓄卡且没有信用卡的用户信息和对应的第4张储蓄卡信息

分解条件

要先找出用户至少有5张储蓄卡

要找出用户没有信用卡

要返回用户信息

额外返回用户的第4张储蓄卡信息

//新创建一个dto用来接收而不是使用临时对象

@Data

@EntityProxy

public class UserDTO2 {

private String id;

private String name;

private String thirdCardType;

private String thirdCardCode;

private String thirdCardBankName;

}

List<UserDTO2> list = easyEntityQuery.queryable(SysUser.class)

.where(user -> {

//用户至少有三张储蓄卡

user.bankCards().where(c -> c.type().eq("储蓄卡")).count().gt(4L);

//用户没有信用卡

user.bankCards().where(c -> c.type().eq("信用卡")).none();

})

.select(user -> {

SysBankCardProxy thirdCard = user.bankCards().orderBy(bankCard -> bankCard.openTime().asc()).element(3);

return new UserDTO2Proxy()

.id().set(user.id())

.name().set(user.name())

.thirdCardType().set(thirdCard.type())

.thirdCardCode().set(thirdCard.code())

.thirdCardBankName().set(thirdCard.bank().name());

}).toList();

最终生成的sql

SELECT t.`id` AS `id`, t.`name` AS `name`, t5.`type` AS `third_card_type`, t5.`code` AS `third_card_code`, t6.`name` AS `third_card_bank_name`

FROM `t_sys_user` t

LEFT JOIN (

SELECT t3.`id`, t3.`uid`, t3.`code`, t3.`type`, t3.`bank_id`

, t3.`open_time`, ROW_NUMBER() OVER (PARTITION BY t3.`uid` ORDER BY t3.`open_time` ASC) AS `__row__`

FROM `t_bank_card` t3

) t5

ON t5.`uid` = t.`id`

AND t5.`__row__` = 4

INNER JOIN `t_bank` t6 ON t6.`id` = t5.`bank_id`

WHERE (

SELECT COUNT(*)

FROM `t_bank_card` t1

WHERE t1.`uid` = t.`id`

AND t1.`type` = '储蓄卡'

) > 4

AND NOT EXISTS (

SELECT 1

FROM `t_bank_card` t2

WHERE t2.`uid` = t.`id`

AND t2.`type` = '信用卡'

LIMIT 1

)

什么你看不懂sql?没关系直接丢给ai让他帮我们看看

image

看来ai还是很懂sql的嘛

聪明的肯定又发现了盲点,你这边生成了两个子查询sql,导致整体sql性能偏弱是否有好的解决方案呢

隐式group,eq提供了子查询合并我们又叫他groupJoin或者隐式group,那么应该怎么做呢,基本上什么代码都不需要动,只需要加一行配置即可

List<UserDTO2> list = easyEntityQuery.queryable(SysUser.class)

//增加这行配置

.configure(s -> s.getBehavior().add(EasyBehaviorEnum.ALL_SUB_QUERY_GROUP_JOIN))

.where(user -> {

//用户至少有三张储蓄卡

user.bankCards().where(c -> c.type().eq("储蓄卡")).count().gt(4L);

//用户没有信用卡

user.bankCards().where(c -> c.type().eq("信用卡")).none();

})

.select(user -> {

SysBankCardProxy thirdCard = user.bankCards().orderBy(bankCard -> bankCard.openTime().asc()).element(3);

return new UserDTO2Proxy()

.id().set(user.id())

.name().set(user.name())

.thirdCardType().set(thirdCard.type())

.thirdCardCode().set(thirdCard.code())

.thirdCardBankName().set(thirdCard.bank().name());

}).toList();

再来看看我们生成的sql

SELECT t.`id` AS `id`, t.`name` AS `name`, t5.`type` AS `third_card_type`, t5.`code` AS `third_card_code`, t6.`name` AS `third_card_bank_name`

FROM `t_sys_user` t

LEFT JOIN (

SELECT t1.`uid` AS `uid`

, COUNT(CASE

WHEN t1.`type` = '储蓄卡' THEN 1

ELSE NULL

END) AS `__count2__`

, COUNT(CASE

WHEN t1.`type` = '信用卡' THEN 1

ELSE NULL

END) <= 0 AS `__none3__`

FROM `t_bank_card` t1

GROUP BY t1.`uid`

) t2

ON t2.`uid` = t.`id`

LEFT JOIN (

SELECT t3.`id`, t3.`uid`, t3.`code`, t3.`type`, t3.`bank_id`

, t3.`open_time`, ROW_NUMBER() OVER (PARTITION BY t3.`uid` ORDER BY t3.`open_time` ASC) AS `__row__`

FROM `t_bank_card` t3

) t5

ON t5.`uid` = t.`id`

AND t5.`__row__` = 4

INNER JOIN `t_bank` t6 ON t6.`id` = t5.`bank_id`

WHERE IFNULL(t2.`__count2__`, 0) > 4

AND IFNULL(t2.`__none3__`, true) = true

好的我们再把sql交给ai重新开启一个会话看看他会怎么回答

image

很好ai再次证明了easy-query的准确性,且easy-query再次证明了他在OLAP中秒杀所有其他ORM

最后的最后我非常感谢您能看到这边我相信eq绝对是你不二的orm选择

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 4:37:03

在线服务器的应用场景都有哪些?

在线服务器作为现代网络架构的核心组件&#xff0c;凭借其强大的计算、存储和数据处理能力&#xff0c;广泛应用于众多领域&#xff0c;深刻改变着人们的生活与工作方式。在线服务器用于对重要数据进行定期备份&#xff0c;防止数据丢失&#xff0c;备份数据可以存储在本地服务…

作者头像 李华
网站建设 2026/4/18 0:26:38

压电雨量监测站:物联网驱动的降雨监测

压电雨量监测站是一款基于物联网技术的现代雨量监测设备&#xff0c;由压电雨量传感器、采集器、太阳能供电系统及立杆支架等部分组成&#xff0c;该设备能够记录分钟级雨量、小时累计雨量、日累计雨量等不同时间维度的数据&#xff0c;并支持自定义日分界时间与降雨报警阈值。…

作者头像 李华
网站建设 2026/4/18 7:03:35

Hyrise终极内存OLAP引擎:为实时数据分析提供高速解决方案

Hyrise终极内存OLAP引擎&#xff1a;为实时数据分析提供高速解决方案 【免费下载链接】hyrise Hyrise is a research in-memory database. 项目地址: https://gitcode.com/gh_mirrors/hy/hyrise 还在为大数据查询性能瓶颈而苦恼吗&#xff1f;面对海量数据时&#xff0c…

作者头像 李华
网站建设 2026/4/16 23:21:38

揭秘阿里Qwen3-Next架构革命:800亿参数仅激活3B的效率突破之路

行业困境&#xff1a;大模型时代的效率瓶颈 【免费下载链接】Qwen3-Next-80B-A3B-Thinking Qwen3-Next-80B-A3B-Thinking 在复杂推理和强化学习任务中超越 30B–32B 同类模型&#xff0c;并在多项基准测试中优于 Gemini-2.5-Flash-Thinking 项目地址: https://ai.gitcode.com…

作者头像 李华
网站建设 2026/4/18 7:03:15

(附源码)SpringBoot游戏代练服务订单管理系统-计算机毕设

SpringBoot游戏代练服务订单管理系统 摘 要 在当前游戏产业蓬勃发展的浪潮下&#xff0c;游戏代练作为一种新兴的服务模式&#xff0c;逐渐在游戏玩家群体中获得了广泛认可。随着代练需求的日益增长&#xff0c;市场对高效、规范的游戏代练服务管理系统的渴望愈发强烈。[3]本 S…

作者头像 李华