团队规定要开始禁用 ORM
公司的多位上司定了下面一条开发规范军则,小弟资质不深,只是看不太懂给的理由,还请大佬们评论一番,给些指导。
禁止使用 ORM 自动生成的 SQL 语句,请将 SQL 直接写在代码里。参数可以使用绑定参数的 API 。比如 ActiveRecord 提供的 update()/insert() 方法,均不可使用。每一个数据库操作应有显式的 SQL 声明。
理由:
维护占生命周期的90% 。
在整个开发和维护过程中,我们一直在干这几件事:
检索:找到它。
追溯:它从哪里来。
跟踪:它到哪里去。
于是:
- 对象必须能够被定位。越精确(比如消除重复项)越好、越容易被记忆越好。
- 强线索。比如显式声明的字段 obj.MyField ,通过 IDE 可以看到它的定义(含注释)、它被多少地方使用到、可以自动重构重命名;而 obj[“MyField”] 只能字符串全文检索了。如果有多个不同地方都叫 MyField ,还得消除歧义(第一点)。
- 原生态。信息传递过程中尽量不发生改变,越静态和固定越容易被跟踪。反之,如果一开始叫 A,传递到第二处叫 B,第三处叫 C ,整个线索可能就乱了。
…(还有好多)
目前 PHP 上的 ORM 如 ActiveRecord 基于约定的表名、动态生成的 SQL 不能满足上述要求。
使用动态生成的SQL,省下来的是第一次开发的时间。在后续的维护过程中则制造负效益。
然后:
- SQL 复制下来就可以贴到数据库工具里跑了,调试、调优都需要。动态生成的,拿到原始语句很困难。
- 动态的语句不是最优的。隐藏了细节,最终性能调优上可能会产生问题。
另外说明下,写下这个理由的 leader 原先主要做的是 .net 开发。
本作品采用《CC 协议》,转载必须注明作者和本文链接
关于 LearnKu
高认可度评论:
叫你领导不要用框架.
难道为了调试 就不能装个 Clockwork
这种不香吗?
ORM的出现本来就是为了规范开发和安全,Eloquent 内部使用的是 PDO 参数绑定,所以大部分的请求是安全的。
你所说的90%的时间在找关于模型的一切,这个就不是模型的问题,而是代码规范的问题,例如这一块是干嘛的,模型命名是不是见名思义,又或者是代码没有分层,所有的业务逻辑往控制器和模型里死怼?
不使用模型,工作量真的会增大(模型替换成SQL语句查询),而且还要顾及到SQL注入的问题。
“SQL 复制下来就可以贴到数据库工具里跑了,调试、调优”,其实Eloquent也有对应的调优的方式,比如避免N+1的问题,比如输出相应sql语句。
感觉完全舍弃Eloquent ORM有点舍本求末了!
讨论这个问题的时候可以先想一下
ORM为我们做了什么:table和model按一定规则绑定curdmodel变成 对应的sql(包含参数处理)sql的结果映射到modelsql语义,做到换db不需要改orm代码上面博主 leader 想要的其实只有
orm的第三点功能(参数处理已经包含,不存在注入问题),实际的开发过程中,换数据库的可能性比较低第四点可以比较不用纠结。下面可以讨论一下 开发效率问题: 在实际开发中一般是读8、写2,讨论对于查询逻辑的考虑就可以看到到底影响有多少。
假设你要获取一个 用户信息(单表查询)
上面两个写法都是一行就能解决掉,效率没差很多吧,并且每一条查询都是有意义的, 一般来说都会被包装成一个服务的方法,比如上面的一句应该被包装在
UserService::GetById(id)中。 使用ORM可能让你觉得很快,快在你可以再各个地方ORM出你要的数据,但是其实当正确的使用不能到处随意用的时候 也没有快到哪里去。在说一点,关于 慢
sql的快速排查,为啥dba通过检测工具发现慢sql的时候,我不能直接把sql拿到项目中全文搜索到, 为啥我要通过监听,然后到日志中去查找。按照最直观的就是直接 搜索项目就完事了。我感觉就是纯为了调试 方便,就是那句“SQL 复制下来就可以贴到数据库工具里跑了,调试、调优都需要。动态生成的,拿到原始语句很困难” :joy:
感觉你们领导们不太懂PHP代码调试,以及对SQL 注入没太有概念。
这个工程量有点大
既然讨厌AR就可以使用 DataMaper 的模式,数据获取的逻辑自己封装,数据获取完成之后在转换到具体的对象中,这里的好处就是很容易处理 Laravel ORM 中不太好搞的关联表聚合成为一个Model。不过纯手写 SQL 给人的压力是比较大的,很容易引入SQL的注入,这种情况下可以引入一个 QueryBuilder 不过看文章的意思估计Leader也不会喜欢。
叫你领导不要用框架.
难道为了调试 就不能装个 Clockwork
这种不香吗?
ORM用的不规范调试确实让人崩溃
看戏模式先
[自己写sql有laravel的orm防注入更好吗]
可以试试 Telescope,不用 ORM 还是舍本逐末吧,PHP 不就是要快吗,自己手敲 SQL,能快到哪里去。
手敲SQL这工作量和开发体验也太糟糕了吧,维护起来也麻烦啊
我上次看到一个CMS,拿到模型对象了,还要在封装一个助手函数
类似这么调用
很好调试。写 ORM,肯定要对比,测试,性能分析,然后上线就没问题了。
使用 ORM ,约定俗成的东西,相当于代码层面规范化了,让大家写出来的代码都差不多,反而更好维护,安全性也更好。
关于:
除了
toSql()方法,上面的朋友也提到了,很多工具可以轻松拿到 SQL 语句。对于 IDE 对
obj [“MyField”]的支持,确实是硬伤。???????????? :joy: :joy: :joy:
我们公司都是严格用模型的
ORM的出现本来就是为了规范开发和安全,Eloquent 内部使用的是 PDO 参数绑定,所以大部分的请求是安全的。
你所说的90%的时间在找关于模型的一切,这个就不是模型的问题,而是代码规范的问题,例如这一块是干嘛的,模型命名是不是见名思义,又或者是代码没有分层,所有的业务逻辑往控制器和模型里死怼?
不使用模型,工作量真的会增大(模型替换成SQL语句查询),而且还要顾及到SQL注入的问题。
“SQL 复制下来就可以贴到数据库工具里跑了,调试、调优”,其实Eloquent也有对应的调优的方式,比如避免N+1的问题,比如输出相应sql语句。
感觉完全舍弃Eloquent ORM有点舍本求末了!
丧心病狂啊,越这样反而越不好维护;新人登场,脱离主流反而不好
这代码之后维护的人会怎么想?
后面代码咋维护?
说一个orm的点,当线上出现慢sql时,根据sql语句去定位时,可能不太方便
你们领导50岁了????
既然领导开心用原生 SQL,就迎合他嘛,也不是触碰底线的事;
ORM 用多了,现在写个 SQL 都得看文档~
这两天正在弄 JAVA ,我怀疑你的领导是写 JAVA 的 :grin: 我现在正在想办法把 SpringData JPA 封装个跟 laravel 差不多的查数据库的类,已经新建好了文件,就缺同时会 JAVA 和 PHP 的大佬指点了
之前认识一个C#的老哥,他的确能做到一条sql,直接查出非常复杂的数据,估计是他的习惯吧。
JAVA 里面查询数据,很多都是下面这样写的,用过 PHP 的,再用这个感觉不太习惯
自己不会使用一些便携工具,却非要回归原始
永远守着自己几十年前那本就一知半解的知识
受罪的是大家
只是他自己这几十年下来可能习惯了,别人会觉得很扯淡
这个leader不行啊
orm好比mysql的template。mysql源码如果不使用template,每几个月还能做到升级一个小版本吗?说到底就是领导为了拿线上有问题的sql,然后去项目代码搜索找到对应开发负责人,好让自己天天可以写ppt
这个leader不得行。不会用就说别人不好用
可以推荐给你领导,使用ORM的简单查询,不要用生成的关联复杂查询,方便后期优化 :joy:
我们就是原生代码,写起来蛮爽的。
:joy: 只要不加班 就慢慢磨吧 而且还有正当理由 原生sql速度肯定要慢得多
ORM某种以上说就是一种约束,多少问题直接查模型就解决了。自己写
SQL的话,你们头还得订更多SQL书写的规范,比如聚合查询别名的命名规范,子查询的书写规范,表别名规范等等。如果能写出优质的sql,肯定是写原生比ORM好。而且也不存在安不安全的问题,ORM不也是PHP封装的吗?除非有人对接收的参数不做数据绑定和过滤。ORM有时候用起来的确很方便,但是一些复杂的sql语句如果硬要用ORM写,太耗时间了特别是不熟悉ORM的情况下。没有谁比谁好,只有谁比谁更适合于某个场景。
快跑! 💨
人和代码有一个能跑就行
人和代码有一个能跑就行
安全性,却带来了更多的负收益。 以上均为个人观点,认同与否雨我无瓜。学会拥抱未来
额。。。
装个 laravel-debugbar 不香吗?
我个人也推荐裸写PDO, :joy:
讨论这个问题的时候可以先想一下
ORM为我们做了什么:table和model按一定规则绑定curdmodel变成 对应的sql(包含参数处理)sql的结果映射到modelsql语义,做到换db不需要改orm代码上面博主 leader 想要的其实只有
orm的第三点功能(参数处理已经包含,不存在注入问题),实际的开发过程中,换数据库的可能性比较低第四点可以比较不用纠结。下面可以讨论一下 开发效率问题: 在实际开发中一般是读8、写2,讨论对于查询逻辑的考虑就可以看到到底影响有多少。
假设你要获取一个 用户信息(单表查询)
上面两个写法都是一行就能解决掉,效率没差很多吧,并且每一条查询都是有意义的, 一般来说都会被包装成一个服务的方法,比如上面的一句应该被包装在
UserService::GetById(id)中。 使用ORM可能让你觉得很快,快在你可以再各个地方ORM出你要的数据,但是其实当正确的使用不能到处随意用的时候 也没有快到哪里去。在说一点,关于 慢
sql的快速排查,为啥dba通过检测工具发现慢sql的时候,我不能直接把sql拿到项目中全文搜索到, 为啥我要通过监听,然后到日志中去查找。按照最直观的就是直接 搜索项目就完事了。只能说是闲的,老板给的需求做太快了
换 java 吧
如果换原生sql就用Go吧 我觉得原生开发效率差不多啊
不用ORM,用原生sql绑定参数方式 那真是脑壳疼啊。
本质上还是规范造成的一系列问题。
如果只是为了定位,,那这种方式有点蠢,其实很简单,把所有的 SQL 都打印出来,然后记录对应执行时间,打印的同时,也记录当前 Request 的 uuid,这样就很快可以定位到某个接口,那么顺着接口排查就行了。用不了几分钟就可以找到对应的位置。
像这种sql 你让他来维护一下他就知道头有多疼了 :joy:
我个人倾向于使用ORM 但是禁用关联查询。
是你们领导太菜了,对于复杂的sql 不建议使用 orm 特性,简单的查询用 orm 挺好用的,现在基本都是微服务架构,查询都是简单查询,联表查询都很少,所以用 orm 还行,而且可以在框架层面增加改动,将执行 sql 在执行的时候输出到日志,类似下面的日志
一直用的原生sql,绑定参数的方式. 很少用orm,虽然也会用,别人问就是你想用哪个就用哪个.
像我这边有很多复杂的业务,如果用orm你会陷入如到一个怪圈.原生sql也复杂,不过好于orm.orm的方法有很多,精通的人很少,如果有人写了修改器或者获取器,稍微菜的人看你代码会直接崩溃.这从哪里来的.
还有个例子,比如用redis.你用laravel框架只知道把驱动设置成redis,用Cache门脸就行.多简单啊.但是redis是有自己的调用语法,比如SETEX jiyikey 60 redis.说白了还得是充实自己.把orm用的再6,换个框架还得重新看.
如果只是完成任务代码就当我没说
一般orm框架不都有打印sql的功能吗?
如果用ORM,那么你既得学会使用ORM,又得学会使用SQL,因为面试往往问的都是SQL。
而如果用SQL,那么你只需要学会SQL就好了。
本来就是相互配合的东西,orm这个东西除了提高开发效率,有时候也是规范,方便维护。如果真的有部分不适合你的操作,就自己再去修改或者封装,没必要抛弃,这里并不是二选一。
这次我站你们领导 :kissing_heart: 你们领导的出发点应该是sql语句的执行效率问题,没考虑代码组织的维护问题 关于sql怎么写,写到哪,这个需要设计一下,全写完整sql语句不是不可以,最好保证这个sql可以多个地方复用
我遇到一个 orm性能的问题,当查询出大量数据时,比如 1 万+,转为 model 的耗时非常久。
这时候使用原生 sql 通过极简 DB 查询,免去 orm自动转为对应 model就非常快。
少量结果集,orm性能还好。