各位还有什么更舒服的写 sql 方法 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
YUyu101
V2EX    问与答

各位还有什么更舒服的写 sql 方法

  YUyu101 2022 年 1 月 27 日 4079 次点击
这是一个创建于 1516 天前的主题,其中的信息可能已经有所发展或是发生改变。

java:jpa ,mybatis

nodejs:typeorm ,knex ,prisma ,为了类型当然要使用 ts

c#:linq ,ef

idea 中手写 sql

以上个人都试过一遍后感觉 prisma 和 linq 这两者友好度最高,不得不说类型提示是否强大很影响体验

最后一个方案是在 idea 下直接手写 sql ,因为 idea 的 sql 提示太强了,连存储过程和自定义类型都能照顾到,但缺点是没法自动衔接到所用的语言的类型系统,java 只能写映射类,js 倒是可能偷个懒当做 any 直接甩出去。

ps:js 的 tagged template 还可以这样用,把参数化查询方法变成字符串模板标签 query ,参数直接塞进查询中,返回一个 promise 结果,即防 sql 注入看起来也十分优雅

await query`select * from article where id = ${id}`; 

也可以加入事务

await query`BEGIN` await query`update article set title = 'linux' where id = ${1}`; await query`COMMIT` 
第 1 条附言    2022 年 1 月 27 日

顺便上一个gif在js+idea直接写sql是什么体验, 关联查询直接用子查询转json, 对于js来说直接就是可以用的object,算是挺适合js的偷懒办法

gif

第 2 条附言    2022 年 1 月 27 日
这 gif 里除了 idea 的提示还有就是 github copilot 提示,copilot 每次剧透我下面要写啥的时候,都让我感觉自己像个傻瓜
18 条回复    2022-01-28 00:08:55 +08:00
levelworm
    1
levelworm  
   2022 年 1 月 27 日   1
作为 ETL 狗,还是喜欢手写 SQL ,然后 Python 调文件 run query 。比较古典的方式。
sagaxu
    2
sagaxu  
   2022 年 1 月 27 日 via Android
多行字符串自己拼 SQL ,零思想负担
ktqFDx9m2Bvfq3y4
    3
ktqFDx9m2Bvfq3y4  
   2022 年 1 月 27 日 via iPhone
以前偏向手写,现在换 ef 。手写一时爽,重构火葬场。
aiuos
    4
aiuos  
   2022 年 1 月 27 日
就纯字符串拼,新人上手也快。弄的花里胡哨的语法,开发成本也高。当然你这个 await query 看起来也不错。
c6h6benzene
    5
c6h6benzene  
   2022 年 1 月 27 日   1
BI 狗表示手写 SQL 最舒服,因为要写后端接触 Springboot 和 JPA 后感觉需要有一点时间来理解。
dcsuibian
    6
dcsuibian  
   2022 年 1 月 27 日
之前一直感觉标签模板没啥用,这么看确实很舒服啊
levelworm
    7
levelworm  
   2022 年 1 月 27 日 via Android
@Chad0000 重构一般是业务需求吧,似乎很难自动化,可能领域不同就是了。
ktqFDx9m2Bvfq3y4
    8
ktqFDx9m2Bvfq3y4  
   2022 年 1 月 27 日 via iPhone   1
@levelworm #7 最简单的就是查看某个字段或者表在哪里被使用了再决定要不要废弃,ef 直接就看出来了:没有被引用则可以放心删除。手写 SQL 和 ef 就相当于 JS 和 TS 的区别,再加上手写 SQL 还不在一个地方则更劣。
msg7086
    9
msg7086  
   2022 年 1 月 27 日
实在没有动力手写 SQL 。

article = Article.find(id) 不香吗。
article.update(title: 'linux') 不香吗。

加入事务:
article.transaction do
  article.update(title: 'linux')
end
golangLover
    10
golangLover  
   2022 年 1 月 27 日 via Android
jpa specification
pannanxu
    11
pannanxu  
   2022 年 1 月 27 日
MyBatis Plus ,单表增删改查直接用方法,复杂点的查询用 xml 手写
OutOfMemery
    12
OutOfMemery  
   2022 年 1 月 27 日
@sagaxu #2 是指代码中拼 sql 吗?写的时候爽,维护的时候难受啊....
sagaxu
    13
sagaxu  
   2022 年 1 月 27 日 via Android
@OutOfMemery 好不好维护看代码组织得是否规范,把拼 SQL 的代码放到约定的目录结构,用约定好的名字,不做 db 以外的逻辑,维护不会比 mybatis 困难。现代语言往往支持多行字符串和模板变量替换,不用写很多加号,比 xml 可读性更高。
james2013
    14
james2013  
   2022 年 1 月 27 日
用 mybatis 进一步封装的,写的很舒服,如 mybatis plus,mapper
单表查询直接在代码中就可以用,多表查询写 sql
而且 entity,controller,service,serviceImpl,mapper.java,mapper.xml 可以用插件或者自己写模版生成,自己只需要写个建表的 sql,方便的很
定义的 dto,通过加注解直接可以将日期格式的转成 yyyy-MM-dd 等格式,方便的很
使用 python 的 peewee 操作数据库,我才发现 mybatis 进一步封装的多香
wdhwg001
    15
wdhwg001  
   2022 年 1 月 27 日
舒服肯定还是 ef 站在顶点,但如果说自由度的话,还是 java 系自由度高。

举个常见的优化例子的话,比如 Hibernate 和 JPA 都支持 addQueryHint ,而 Query Hint 在其他 ORM 里并不存在。

C#的 EF/Linq 是在这方面走的比较近的,有讨论得比较深入的 Issue: https://github.com/dotnet/efcore/issues/6717

并且,硬要写的话也可以用 DbCommandInterceptor 搞: https://stackoverflow.com/questions/8031069/how-can-i-specify-an-index-hint-in-entity-framework/67743682

其他家就真没了。说实话,我觉得 Query Hint 这种东西还是挺重要的,毕竟强制索引也算是一种基础优化方式了。
adoal
    16
adoal  
   2022 年 1 月 27 日 via iPhone
手写 SQL 语句(但是用参数化查询)和手拼完整的 SQL 语句字符串是两码事…都 2022 年了,上面说手拼字符串的各位不会真的是把查询条件里的值也手拼进字符串里的吧。
micean
    17
micean  
   2022 年 1 月 27 日
js 端这么写:
const a = Table('a')

SQL.select(
a.id, a.name.as("username")
).from(a).where( a.age.greateThan(3) )
levelworm
    18
levelworm  
   2022 年 1 月 28 日
@Chad0000 明白你的意思了,这个的确 SQL 弄不来,SQL 最多就是查系统表看看各个 object 有哪里用到的,但是如果是外界的程序,就不行了。
关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1536 人在线   最高记录 6679       Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 44ms UTC 16:53 PVG 00:53 LAX 09:53 JFK 12:53
Do have faith in what you're doing.
ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86