news 2026/4/26 15:39:56

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/23 12:25:41

群晖引导工具选择困境:从技术小白到专业玩家的完整指南

群晖引导工具选择困境&#xff1a;从技术小白到专业玩家的完整指南 【免费下载链接】rr Redpill Recovery (arpl-i18n) 项目地址: https://gitcode.com/gh_mirrors/rr2/rr 你是否曾经面对这样的场景&#xff1a;精心挑选的NAS硬件已就位&#xff0c;却卡在引导系统这一步…

作者头像 李华
网站建设 2026/4/23 12:10:53

好写作AI:硕士生狂喜!2小时“肝”出文献综述初稿的“魔法”是真的

凌晨两点&#xff0c;望着空白的文档和PDF堆积如山的文献文件夹&#xff0c;硕士生小李感觉自己的文献综述就像一座永远无法逾越的高山。直到他尝试了一种全新的“打法”……如果你也曾在文献综述的“苦海”里挣扎——面对数百篇文献不知从何读起&#xff0c;读完后思路混乱难以…

作者头像 李华
网站建设 2026/4/23 12:50:15

14、邮件系统的插件使用与安全配置指南

邮件系统的插件使用与安全配置指南 在当今数字化的时代,邮件系统成为了人们日常工作和生活中不可或缺的一部分。无论是个人用户还是企业用户,都依赖邮件系统进行信息交流和业务沟通。本文将围绕SquirrelMail邮件系统的插件使用以及邮件服务器的安全配置展开详细介绍。 1. S…

作者头像 李华
网站建设 2026/4/23 13:36:49

解锁Obsidian颜值新境界:AnuPpuccin主题深度体验指南

解锁Obsidian颜值新境界&#xff1a;AnuPpuccin主题深度体验指南 【免费下载链接】AnuPpuccin Personal theme for Obsidian 项目地址: https://gitcode.com/gh_mirrors/an/AnuPpuccin 还在为Obsidian单调的界面而苦恼吗&#xff1f;AnuPpuccin主题或许就是你一直在寻找…

作者头像 李华