golangORMORMORM然后我总结了他们呢的一些共性和差异点,于是形成了本文的主要内容。
code firstdatabase firstjavac#phppythongo如果你需要做技术选型,或者做技术研究,或者类似于我做框架开发,或者单纯地了解各语言的差异,或者就是想吹个牛,建议保存或收藏。如果本文所涉及到的内容有任何不正确,欢迎批评指正。
温馨提示,本文会有一些戏谑或者调侃成分,并非对某些语言或者语言的使用者有任何歧视意见。
如果对你造成了某些伤害,请多包涵。
什么是SQL编写难题如果你是做web开发,那么必然需要保存数据到数据库,这个时候你必须熟悉使用sql语句来读写数据库。
sql本身不难,命令也就那几个,关键字也不算多,但是为什么编写sql会成为难题呢?
比如下面的sql
sql但是,如果你需要写下面的sql呢?
sql再稍微复杂点,如果是下面的sql?
sql如上面的sql所示,SQL编写难题在于以下几方面。
要保证字段正确
应该有的字段不能少,不应该有的字段不能多。
mobilemobike并且项目越大,表越多,字段越多,这种拼写错误发生的可能性越大。以至于可以肯定的说,100%的可能性会出现。
要特别注意sql语法
fromformsql编辑器不会有sql的语法提示
常见的编码用的软件,对于sql相关的代码,不会有语法提示,也不会有表名提示,字段名提示。
最终的代码质量如何全凭你的眼力,经验,能力。
很显然,既然存在该难题,那么哪个ORM能解决该难题,就应该算得上好,如果不能解决,则不能称之为好。
什么是code first 和 database first这俩概念并不是新概念,但是我估计大多数开发者并不熟悉。
所谓 code first, 相近的词是 model fist, 意思是模型优先,指的是在设计和开发系统时,优先和重点做的工作是设计业务模型,然后根据业务模型去创建数据库。
所谓 database first,意思是数据库优先,指的是在设计和开发系统时,优先和重点做的工作是创建数据库结构,然后去实现业务。
这里我提到了几个词语,可能在不同的语言里叫法不一样,可能不同的人的叫法也不一样,为了下述方便,我们举例子来说。
code first 例子
假设我是一个对电商系统完全不懂的小白,手头上也没有如何设计电商系统的资料,我和我的伙伴只是模糊地知道电商系统主要业务就是处理订单。
然后我大概会知道这个订单,主要的信息包括哪个用户下单,什么时间下单,有哪几种商品,数量分别是多少,根据这些已有的信息,我可以设计出来业务模型如下
很简单,对吧,这个模型很匹配我目前对系统的认知。接下来会做各种业务逻辑,最后要做的是将订单模型的数据保存到数据库。但是在保存数据到数据库的时候,就有一些考虑了。
OrderModel但是我是电商小白,不是数据库小白啊,这样存储的话,肯定不利于统计订单商品的。
OrderModel然后将 orderDetail 的信息进行再次分解,放到另一个类里
orderorder_detailOrderEntityOrderDetailEntityOrderModelorderorder_detail这就是 code first ,注意这个过程的关键点,我优先考虑的是模型和业务实现,后面将业务模型数据进行分解和保存是次要的,非优先的。
database first 例子
假设我是一个对电商系统非常熟悉的老鸟,之前做过很多电商系统,那么我在做新的电商系统的时候,就完全可以先设计数据库。
orderorder_detailOrderEntityOrderDetailEntityOrderModel这就是 database first ,注意这个过程的关键点,我优先考虑的是数据库结构和数据表结构。
两种方式对比
OrderModelorderorder_detailorderorder_detailorderorder_detail至此,我们可以有以下粗浅的判断:
对于新项目,不熟悉的业务,code first 模式更适合一些
对于老项目,熟悉的业务,database first 模式更合适一些
如果两种模式都可以的话,优先使用 code first 模式,便于理解业务,把控项目
如果哪个ORM支持 code first , 我们可以稍稍认为它更好一些
Java体系的ormJava语言是web开发领域处于领先地位,这一点无可置疑。它的优点很明显,但是缺点也不是没有。
国内应用比较广泛的orm是Mybatis,以及衍生品Mybatis-plus等
实际上Mybatis团队还出了另外一款产品,MyBatis Dynamic SQL,国内我见用的不多,讨论都较少。英文还可以的同学,可以看下面的文档。
另外还有 jOOQ, 实际上跟 MyBatis Dynamic SQL 非常类似,有兴趣的可以去翻翻
下面,我们举一些例子,来对比一下他们的基本操作
Java体系的Mybatis
单就orm这一块,国内用的最多的应该是Mybatis,说到它的使用体验吧,那简直是一言难尽。
xmlxmlxmlsqlxmlxmlSQL编写难题Java体系的Mybatis-plus
xmlxmlsql但是,请你注意我的用词,是减少了一些。
对于连表操作,嵌套查询等涉及到多表操作的事情,它就不行了,为啥不行,因为根本就不支持啊。
xmlSQL编写难题Java体系的Mybatis3 Dynamic Sql
值得一提的是Mybatis3 Dynamic Sql,翻译一下就是动态sql。还是刚才说的国内我见用的不多,讨论都较少,但是评价看上去挺好。
简单来说,可以根据不同条件拼接出sql语句。不同于上面的Mybatis,这些sql语句是程序运行时生成的,而不是提前写好的,或者定义好的。
它的使用流程是,先在数据库里定义好数据表,然后创建模型文件,让然后通过命令行工具,将每一个表生成如下的支持文件
可以看出,这里的主要功能能是将表内的字段,与java项目里的类里面的属性,做了一一映射。
接下来你在开发的时候,就不用关心表名,以及字段名了,直接使用刚才生成的类,以及类下面的那些属性。具体如下
如上面的代码,好处有以下四点
SQL编写难题PersonDynamicSqlSupportdatabase firstC#体系的ormC# 在工业领域,游戏领域用的多一些,在web领域少一些。
它也有自己的orm,名字叫 Entity Framework Core, 一直都是微软公司在维护。
下面是一个典型的联表查询
这句代码的主要作用是,将数据库里的Posts表,与Post_Metas表做内联操作,然后取出Post.ID等于1的数据
这里出现的Post,以及Meta都是提前定义好的模型,也就是类。 Post.ID 是 Post 的一个属性,也是提前定义好的。
SQL编写难题code first对比java的Mybatis以及Mybatis3 Dynamic Sql来说,你可以脑补一下下面的场景
PHP体系的ormlaravelsymfonyPHP体系的laravel
laravel这里没有使用模型(就算使用了也差不多),代码里出现的 users 就是数据库表的名字, name 是 users 表里的字段名,他们是被直接写入代码的
SQL编写难题database firstPHP体系的symfony
这个框架历史也比较悠久了,它使用了 Doctrine 找个类库作为orm
使用它之前,也需要先定义模型,然后生成支持文件,然后建表,但是在实际使用的时候,还是和laravel一样,表名,字段名都需要硬编码
SQL编写难题code firstpython体系的orm在python领域,有一个非常著名的框架,叫django, 另外一个比较出名的叫flask, 前者追求大而全,后者追求小而精
python体系的django
django推荐的开发方法,也是先建模型,但是在查询的时候,这建立的模型,基本上毫无用处
如上连表查询的代码,values('title','publish__name') 这里面写的全都是字段名,硬编码进去,进而产生sql语句,查询出结果
SQL编写难题code firstpython体系的flask
flask本身没有orm,一般搭配 sqlalchemy 使用
使用 sqlalchemy 的时候,一般也是先建模型,然后查询的时候,可以直接使用模型的属性,而无须硬编码
如上 Article.id 即是 Article 模型下的 id 属性
SQL编写难题code firstgo体系的orm在go体系,orm比较多,属于百花齐放的形态,比如国内用的多得gorm以及gorm gen,国外比较多的ent, 当然还有我自己写的 arom
go体系下的gorm
使用gorm,一般的流程是你先建立模型,然后使用类似如下的代码进行操作
这是一个嵌套查询,虽然定义了模型,但是查询的时候并没有使用模型的属性,而是输入硬编码
SQL编写难题code firstgo体系下的gorm gen
gorm gen 是 gorm 团队开发的另一款产品,和mybaits下的Mybatis3 Dynamic Sql比较像
它的流程是 先创建数据表,然后使用工具生成结构体(类)和支持代码, 然后再使用生成的结构体
它生成的比较关键的代码如下
注意看,其中大多数代码的作用是啥?不意外,就是将结构体的属性与表字段做映射关系
_user.Name 对应 name
_user.Age 对应 age
如此,跟mybaits下的Mybatis3 Dynamic Sql的思路非常一致
典型查询代码如下
这是一个分组查询,定义了模型,也使用了模型的属性。
但是呢,它需要使用工具生成额外的支持代码,并且需要先定义数据表
SQL编写难题database firstgo体系下的ent
ent 是 facebook公司开发的Orm产品,与 gorm gen 有相通,也有不同
相同点在于,都是利用工具生成实体与数据表字段的映射关系
不同点在于gorm gen先有表和字段,然后生成实体
ent是没有表和字段,你自己手动配置,配置完了一起生成实体和建表
接下来,看一眼ent生成的映射关系
有了映射关系,使用起来就比较简单了
注意,这里没有硬编码
它需要使用工具生成额外的支持代码,并且需要先配置表结构
SQL编写难题database firstgo体系下的aorm
aorm 是我自己开发的orm库,吸取了ef core 的一些优点,比较核心的步骤如下
和大多数orm一样,需要先建立模型,比如
然后实例化它,并且保存起来
然后即可使用
SQL编写难题code first总结本文,我们提出了两个衡量orm功能的原则,并且对比了几大主流后端语言的orm,汇总列表如下
单就从这张表来说,不考虑其他条件,在做orm技术选型时,
SQL编写难题SQL编写难题code firstSQL编写难题SQL编写难题code firstSQL编写难题code first好了,文章写两天了,终于写完了。
如果我有说的不合适,或者不对的地方,请在下面狠狠的批评我。
参考文档