大家喜欢用 ORM 还是直接写 SQL

2023-12-29 12:50:20 +08:00
 gitrebase

OP 主要用的 Java 和 Go ,但是感觉这俩主流语言的 ORM 框架( JPA 、GORM )都不如 C#、Python 的 ORM 好用( JOOQ 、ent 、XORM 感觉国内用的还是有点少),而 SQL / SQL builder ( JdbcTemplate 、sqlx )在动态条件查询时需要在代码里拼 SQL 字符串也有点🥚疼

其实就是最近在玩 Spring 新出的 JdbcClient ( JdbcTemplate 的封装版),感觉在 Java 有多行字符串后,在 Java 代码里写 SQL 完全不是什么问题,而且也不用使用难用的 XML 去定义 resultMap (直接在 Java 里定义 record 或者 class 然后用构造器就可以了)

public record User(Long id, String name, Integer sex) {
}

@GetMapping("/users/in")
public Iterable<User> listInIds(@RequestParam List<Integer> ids) {
    return jdbcClient.sql("""
            SELECT *
            FROM `user`
            WHERE `id` IN (:ids)
            """)
            .param("ids", ids)
            .query(User.class)
            .list();
}

但是在碰到动态条件的 where 语句的时候,在 Java 代码里手搓 SQL 看着也很让人头大……这时候 MyBatis 提供的 dynamic SQL 就很好用了

但真的不喜欢 XML……

MyBatis-Plus 也了解过,但说不上来为什么,总是感觉不太喜欢这个库……

19609 次点击
所在节点    程序员
155 条回复
idealhs
2023-12-29 13:52:16 +08:00
JAVA 里如果有 EF Core 就不会有 ORM 好不好用这个问题出现了
woodfizky
2023-12-29 13:52:55 +08:00
我只知道原生 SQL 防 SQL 注入很麻烦,特别是自己拼的原生 SQL 。而如果你自己做防注入了,又很像在干 ORM 该干的事情。

ORM 的话,因为我写 python ,公司的项目用的 SQLAlchemy+FastAPI+Gino ,稍微有点学习成本,有些写法文档也没介绍,会有隐藏的坑,但是熟悉之后写起来还是挺舒服的。

性能肯定是原生好,因为 ORM 除了负责把代码对象变成 SQL 语句去执行,还要把查询结果又加载成代码对象,写起来是很舒服,但是中间的转换是有代价的。
6167
2023-12-29 13:53:05 +08:00
python+sqlalchemy ,非常好用,三四张表 join 起来没什么问题
wangkun025
2023-12-29 13:54:18 +08:00
rubiest ,必然是 ORM 啊。
lyxxxh2
2023-12-29 13:57:40 +08:00
工作 5 年了 只用 orm
没有 orm 完成不了的 sql
musi
2023-12-29 14:01:29 +08:00
前端,喜欢 orm ,但是写 go 发现没有一个 orm 是好用的。。。
coinbase
2023-12-29 14:04:09 +08:00
复杂的用 SQL, 简单的逻辑判断用 ORM 更方便
cheng6563
2023-12-29 14:07:01 +08:00
简单 CURD 用 ORM ,复杂查询写 SQL (比如连表或者用了 OR )
twofox
2023-12-29 14:09:48 +08:00
歪个楼,Java 21 的字符模板真的好丑陋
skyworker
2023-12-29 14:13:01 +08:00
@Features 确切说, 是 Eloquent 天下第一
eliot121450375
2023-12-29 14:13:20 +08:00
@woodfizky alchemy2.0 自身也有对异步的支持,为啥要用 gino 呢?我没接触过 gino
woodfizky
2023-12-29 14:15:54 +08:00
@eliot121450375 可以说是遗留问题了。。当时还用的是 SQLAlchemy1.3 ,那时候还不支持异步。
不过 Gino 可以兼容 SQLAlchemy 的语法,加上连接池用的也是 Gino 的,就这么用下来了。
coinbase
2023-12-29 14:16:42 +08:00
--portfolio
WITH all_transfers AS (
SELECT "from", "to", token_address, -value AS value_diff
FROM erc20_transfers_from_shard
WHERE "from" = LOWER('0x9B1bbecdf6409ff6F7cAE9DA2C4d2C7f6b8CF9E9')
UNION ALL
SELECT "from", "to", token_address, value AS value_diff
FROM erc20_transfers_to_shard
WHERE "to" = LOWER('0x9B1bbecdf6409ff6F7cAE9DA2C4d2C7f6b8CF9E9')
),
sum_transfer AS (
SELECT token_address, SUM(value_diff) AS sum_value
FROM all_transfers
GROUP BY token_address
),
price_usd_token AS (
SELECT sum_transfer.token_address, sum_transfer.sum_value, tokens.price_usd, tokens.decimals, tokens.symbol,
(tokens.price_usd * sum_transfer.sum_value) / POWER(10, tokens.decimals) AS total_value
FROM sum_transfer
INNER JOIN tokens ON tokens.address = sum_transfer.token_address
WHERE tokens.decimals != 0 AND tokens.decimals IS NOT NULL AND tokens.is_honeypot = false
)
SELECT token_address, symbol, sum_value, total_value, price_usd
FROM price_usd_token
WHERE total_value IS NOT NULL AND total_value > 0
ORDER BY total_value DESC;


复杂的还是 SQL 舒服
jtsai
2023-12-29 14:19:06 +08:00
SQL ,ORM 把简单的问题搞复杂了
codingmiao
2023-12-29 14:25:30 +08:00
混着用,现在的 ORM 框架还配有代码生成器,传个表名进去一波帮你生成到前端 crud 界面了,还是很省心的。但是复杂业务用 ORM 就有点多余了。
zhhqiang
2023-12-29 14:28:33 +08:00
ORM 对一些业务处理很方便 sql 也很重要
monkeyWie
2023-12-29 14:32:37 +08:00
那些说喜欢 ORM 的来,多表链接 + 多个子查询 + 聚合查询 + 动态条件,用 ORM 给我写个看看
jiayouzl
2023-12-29 14:33:07 +08:00
肯定 Orm 啊,后期维护都简单很多,纯 Sql 语句后期维护太麻烦了。
encro
2023-12-29 14:33:25 +08:00
@just1

python 不是只有 3 个嘛,django,sqlalchemy,Peewee
flyingfz
2023-12-29 14:33:58 +08:00
原来用 C# 的时候,用过 Stack Overflow 开源的 dapper , 用 C#的 强烈推荐 这个库。

现在基本是手写 sql .
事务控制 、 复杂 SQL 等场景, 还是手写舒服。 防注入的话,不要拼接客户端的内容,查询用参数就 OK 了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1004383

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX