Loading... > 此篇文章是先前在知乎上回答同名问题[《laravel框架中的Model操作数据库 , 相比DB类有什么明显的优越性吗?》](https://www.zhihu.com/question/49649216/answer/302495256)时所写,因为这个问题比较有普遍意义,所以将当时在知乎上的回答复制在此,作为我们[《Laravel 5.7优雅实战入门(一)》](https://study.163.com/course/courseMain.htm?courseId=1003163020&share=2&shareId=1018568251)这一课程的扩展阅读供学习和参考。 ### 以下是知乎提问者的提问补充: *目前正在学习laravel框架 , 但是在模拟项目开发的过程中 , 发现使用Model 对 MySQL数据库操作 , 相比DB类来说并没有什么明显的优越性 , 那么在实际开发的过程中 , 使用Model来对数据进行操作 , 除了让代码的可读性更高之外, 能带来什么其他好处呢?* ### 以下是当时我的回答: 首先,需要说明的是laravel提供了三种数据操作方式:raw SQL, query builder和Eloquent ORM。在表现形式上注意的是,raw SQL和query builder用的都是DB,不能混为一谈 ```php $users = DB::select('select * from users where active = ?', [1]); ``` 这样的时候就是raw SQL,或者说是原生的SQL语句 ```php $users = DB::table('users')->get(); ``` 这个时候就是query builder,其背后基于的是我们熟悉的PDO连接。 至于SQL注入的防护,其实query builder和Eloquent ORM都已经有了,而raw SQL当然就不可能有了,毕竟控制权在你自己手里,你总不能自己攻击自己吧,哈哈 至于说其他人提到的数据库类型,laravel默认支持的是这么几种: * MySQL * PostgreSQL * SQLite * SQL Server 可以看到都是关系型的数据库,也就是说raw SQL, query builder和Eloquent ORM这三种操作方式都能胜任这些数据库,不存在说后期换数据库导致不支持。 至于说NoSQL数据库,比如redis、MongoDB等,这些一般得通过第三方组件来实现,操作的时候往往是直接操作第三方组件的相应类,比如Redis类。 我想题主所说的DB类,应该指的是query builder,接下来看看Eloquent ORM相对于query builder的优劣势: ### 优势: 1. Eloquent ORM简便易懂,既提高了开发效率,也提高了代码的可读性,方便后期维护,这是最主要的优势,也正是因为此,你应该在绝大多数场合下使用它,因为现在的共识是开发效率要远比单方面的性能重要的多。 2. Eloquent Relationship——也即是Model之间的关系,通过关系,你很容易地操作不同业务模型之间的逻辑或业务关系,如果丢掉这一点,那么可以说,本来一两行就解决的逻辑,你肯定不得不十来行或者几十行来解决,在相当程度上,也就不可能体验到laravel的真正优雅了,单在这一点上,非得全程用DB就相当于跟OOP的编程规范背道而驰了,有点拒绝进步的意味了。Eloquent背后实现的是ActiveRecord design pattern,这个可以说是现代流行框架的必备实现,当然不要拿国内的那些来说事~ 3. 在安全性上,Eloquent确实也要比query builder或者说DB::table()要安全得多,当然这个不是指之前说的SQL注入,而是比如说Mass Assignment,也即批量的字段操作时,Eloquent可以很方便地通过$fillable或者$guarded属性来定义哪些栏允许或不允许批量插入修改等。 4. 比如说Eloquent里的scope,可以用来预定义一些常见的、重复性的数据查询,非常方便,用DB::table()就没法享用了 5. route model binding:基于路由参数自动地给我们获取一个model实例,就根本不需要我们再去基于id或uuid之类的从数据库中额外查找了,这个DB就完全不沾边了 6. 类似的还有Form Model Binding,表单与model数据的自动绑定,在我们编辑表单时非常省心,不用传值就能自动加载已有数据了,这跟DB也毫无关系了 7. model accessor 和 mutator: model属性的获取器和修改器,无论在get或set某一个model属性的时候,都可以自动执行我们额外定义的逻辑,这也跟DB无缘 8. Event事件,laravel里提供了很多Model Event,包括优雅的observer,可以在数据发生变化时去自动地执行相应地事件,同样的,用DB::table()就没法享用了,很难想象这么好的特性为何放弃呢?~ 9. 现在写API非常流行,我们得返回一个Model数据的对应的JSON格式,当然在具体返回的时候我们经常还需要对其数据加以操作,比如有的显示,有的不显示,有的还要带上其所属关系的对应数据,这个时候我们laravel新推出的API Resource非常省心,允许你提前定义单个model或多个model(collection)的json返回形式,而要用API resource的前提就是你得有model对吧?这个时候搞DB,就完全无从下手了 10. 说到写API,可能依然还有不少人对lumen抱有希望?说既然是搞API,那用lumen好了,然后lumen里默认没开启model,只有DB,这是否说这种情况下DB就取代Model了呢?但实际的情况下,结合这些年来大部分的数据反馈,一方面使用lumen搞API的,大部分都不自觉地开启了model,开启了orm,甚至慢慢地开启了越来越多laravel里的功能,导致最后的lumen就跟laravel差不多了;另一方面,当然也是因为前者的原因,现在开发API优先使用laravel,而不是lumen,也已经基本成为共识,国外社区唱衰lumen的大有人在。这其中,我想Eloquent model的作用功不可没。 11. 其他的暂时未想到,留个空,感觉还有似的 ### 劣势: 1. Eloquent相比于DB,在有些时候会导致性能的略微下降,但是这也完全不需要顾虑,因为优化性能的方法实在太多,各个方面都都有途径去提升,但是开发的便捷与效率,你却不容易轻易获得,否则laravel也不会如此流行了 2. 有时候遇到了复杂的逻辑,确实用Eloquent会不容易实现,这个时候你就不得不借助于DB了,往往这个时候我们会用一下DB::raw() ### 结论: 使用Eloquent ORM是一种优雅选择,不是必然选择。在可以的时候,要尽可能地用Eloquent ORM,实在需要的时候,偶尔再借助于DB,这期间往往你会发现,99%以上的时候你都是在用Eloquent ORM Last modification:March 7, 2023 © Allow specification reprint Like 如果觉得我的文章对你有用,请随意赞赏