V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
YUyu101
V2EX  ›  问与答

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

  •  1
     
  •   YUyu101 · 2022-01-27 01:07:14 +08:00 · 3180 次点击
    这是一个创建于 1039 天前的主题,其中的信息可能已经有所发展或是发生改变。

    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-01-27 12:36:27 +08:00

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

    gif

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

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

    加入事务:
    article.transaction do
      article.update(title: 'linux')
    end
    golangLover
        10
    golangLover  
       2022-01-27 09:04:17 +08:00 via Android
    jpa specification
    pannanxu
        11
    pannanxu  
       2022-01-27 09:24:20 +08:00
    MyBatis Plus ,单表增删改查直接用方法,复杂点的查询用 xml 手写
    OutOfMemery
        12
    OutOfMemery  
       2022-01-27 09:26:10 +08:00
    @sagaxu #2 是指代码中拼 sql 吗?写的时候爽,维护的时候难受啊....
    sagaxu
        13
    sagaxu  
       2022-01-27 09:48:47 +08:00 via Android
    @OutOfMemery 好不好维护看代码组织得是否规范,把拼 SQL 的代码放到约定的目录结构,用约定好的名字,不做 db 以外的逻辑,维护不会比 mybatis 困难。现代语言往往支持多行字符串和模板变量替换,不用写很多加号,比 xml 可读性更高。
    james2013
        14
    james2013  
       2022-01-27 10:14:32 +08:00
    用 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-01-27 10:25:00 +08:00
    舒服肯定还是 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-01-27 11:15:30 +08:00 via iPhone
    手写 SQL 语句(但是用参数化查询)和手拼完整的 SQL 语句字符串是两码事…都 2022 年了,上面说手拼字符串的各位不会真的是把查询条件里的值也手拼进字符串里的吧。
    micean
        17
    micean  
       2022-01-27 11:59:39 +08:00
    js 端这么写:
    const a = Table('a')

    SQL.select(
    a.id, a.name.as("username")
    ).from(a).where( a.age.greateThan(3) )
    levelworm
        18
    levelworm  
       2022-01-28 00:08:55 +08:00
    @Chad0000 明白你的意思了,这个的确 SQL 弄不来,SQL 最多就是查系统表看看各个 object 有哪里用到的,但是如果是外界的程序,就不行了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1046 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 19:01 · PVG 03:01 · LAX 11:01 · JFK 14:01
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.