本文正在参与 「金石计划 . 瓜分6万现金大奖」

本次主要来聊聊关于 ORM 的内容,欢迎评论沟通,欢迎批评指正

分别从如下 4 个方面来展开

  • ORM 他是个啥?
  • 为什么要用 ORM?
  • ORM 给咱们带来了哪些问题?
  • 如何去考虑是否要运用 ORM?

ORM 他是个啥?

一提到 ORM 许多同学知道他是跟数据库相关的一个内容,但是并不清楚他究竟是这个啥,自己需不需求,究竟怎么玩?

实践上 ORM 就那么一回事,从这三个字母就能够看到

O:Object

R:Relational

M:Mapping

目标关系映射,即关系型数据库和咱们的实体事务目标来进行一个映射,对与咱们运用 ORM 目标来说,就直接去运用其对应的各种办法即达到主动持久化的意图,无需重视详细的 sql 细节

由于 ORM 已经为你隐藏了关于 sql 的部分,让不熟悉 sql 的 xdm 也能够很好的上手

只需你知道如何运用函数,运用目标里面的办法究竟你的数据操作意图即可

为什么要用 ORM?

为什么要运用 ORM 呢?莫非出了一个新的东西,咱们就必定要用吗?自然是要知道他的好,咱们才会去运用

结论先放在前面,运用 ORM

  • 能够削减咱们重复的写垃圾代码,能够进步咱们的工作功率,降低开发成本
  • 拜访数据的时分,能够运用抽象的办法,用起来非常简洁
  • 以及 orm 带来的各种奇淫巧技

举一个 gorm 的比如

在 GO 中咱们拜访 mysql 关系型数据库,数据库中提前先创立好了数据库,数据表,以及 3 条记载

我们要不要使用 ORM?

GO 中有给咱们供给对应的库

import "database/sql"
import _ "github.com/go-sql-driver/mysql"

咱们能够运用 sql.Open() 衔接 mysql 数据库

func Connect() (*sql.DB, error) {
   db, err := sql.Open("mysql", "root:123456@/test_gorm")
   if err != nil {
      return nil, err
   }
   return db, nil
}

获取到 db 句柄之后,咱们能够通过这样的办法,输入 sql 句子来查询数据

我们要不要使用 ORM?

能够发现,本次的查询句子是 select id,name,email,member_number,address from users where id = ? ,咱们再一条数据一条数据的读取出来(此处需求留意运用读取 rows.Next() 的时分,需求读取完毕之后,关闭句柄,不然会资源泄漏

我们要不要使用 ORM?

那么假如咱们换成其他查询句子,或者其他增删改的句子呢?

回顾一下曾经各种疯狂写重复代码 sql 代码的状况,流程是相同的,代码结构也是相似的,写着差不多的代码,过着差不多的人生吗?

甚至这一块的代码许多或许都是复制粘贴,然后改改 sql,改改响应成果

这也太无聊和重复了,咱们还真的是个码农了?别人搬砖,咱们搬代码?

这不,这个时分,咱们就能够运用 ORM 来协助咱们进步生产功率, 削减咱们的低价值重复劳动,能够留更多的时刻来进行思考和优化

这样,咱们运用 gorm 的话,衔接数据咱们就能够这样来写

func Connect(user, pwd, ip, port string) (*gorm.DB, error) {
   db, err := gorm.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s:%s)/test_gorm?charset=utf8&parseTime=True&loc=Local", user, pwd, ip, port))
   if err != nil {
      return nil, err
   }
   return db, nil
}

上述的查询就会变成这样的

我们要不要使用 ORM?

有没有发现,对应的当地,运用 orm 的办法,对于咱们来说,其实就是需求查询一条数据,完全都不需求去关心 sql ,只需求依照目标去运用办法就能够查询咱们想要的数据

我们要不要使用 ORM?

看到这里,有没有开始觉得 ORM 仍是很香的,至少咱们写数据持久化的时分,就不需求写那么多重复代码了,运用 ORM 便利高效

gorm 简述和提示

看了上述比如是否会有这些疑问,

  1. Import 包的时分为什么导入了又不用?
  1. 为什么衔接数据库的时分需求带上 mysql 字符串?
import _ "github.com/go-sql-driver/mysql"

首先,一个库假如不用的话,那当然是没有必要导入的,导入了正式由于需求运用

能够看到 mysql 包中的 init 函数,实践上就是做一个注册,用一个有效的姓名,对一个这一个数据库引擎

func init() {
   sql.Register("mysql", &MySQLDriver{})
}

Register 实现如下

我们要不要使用 ORM?

能够看到在sql包里面有一个大局map,里把存放了mysql这个姓名的driver

我们要不要使用 ORM?

再来检查 gorm.Open() 的实现就一目了然了

gorm.Open 中调用了 sql.Open , sql.Open 中去从大局的 map driver中获取 mysql 字符串对应的引擎

gorm.Open

我们要不要使用 ORM?

sql.Open

我们要不要使用 ORM?

这一块就到这里,假如需求体系的学习和了解 gorm,能够从这里进入:

  • www.topgoer.cn/docs/gorm/g…
  • gorm.io/
  1. gorm.Open 为什么要带上 charset=utf8&parseTime=True&loc=Local

其间 charset 是表明字符编码

parseTime 为 True ,表明处理数据的时分,会去解析时刻

loc=Local 表明入库的时分,运用的是本地时区

以及 gorm 有没有其他的坑?

实践上在运用 gorm 的时分,仍是会有许多坑等着咱们,此处先给大家避避坑

与其说是坑,实践上仍是自己去运用一个技能的时分对其不够了解,认知没有对齐导致的

  • 创立数据表的坑

运用 gorm 创立数据表的时分,会先要界说一个根本的数据模型,表明数据表中有哪些字段,其间 gorm 默许给咱们供给了一些默许 model,依据实践状况运用即可

type Model struct {
   ID        uint `gorm:"primary_key"`
   CreatedAt time.Time
   UpdatedAt time.Time
   DeletedAt *time.Time `sql:"index"`
}

例如咱们子界说的表结构是这样的:

我们要不要使用 ORM?

创立出来的表格名为 users ,咱们能够运用如下句子禁用表名复数,或者自界说一个表名都是能够的

db.SingularTable(true)
  • 解析时刻的坑

上述运用 gorm.Open() 衔接数据库的时分,咱们指定了 parseTime=True ,那么后续处理时刻类型的数据就不会有问题,假如不指定的话,gorm 处理时刻类型的数据会处理出错

  • 想当然的坑

ORM 当然用起来便利,不动 sql 的人用起来也很爽,但是一些根本的操作仍是要留意的,不然会对功能影响非常大

例如,查询一批数据的时分获取会想当然的这样来写

// 伪代码,示意一波
userList:=[]int{1, 3, 5}
user := dao.User{}
for _,v := range userList {
    db.First(&user, v)
}

或许在写其他逻辑的时分这样写好像没啥问题,但是你要明白现在是操作数据库,怎么能够循环操作数据库呢?假如 demo 中的 userList 足够的大,那么成果可想而知

在 gorm 完全能够运用 where 的办法来达到咱们的查询意图,仍是需求咱们理解了之后,灵活运用,不要生搬硬套,例如

users := make([]dao.User, 0)
db.Where("id in (?)", []int{1, 2, 3}).Find(&users)

ORM 给咱们带来了哪些问题?

Xdm 闭着眼睛想一下,原来是直接就运用 sql 去操作数据库的,现在咱们通过了一层 gorm 目标,自然是会对咱们的功能带来影响的,并且 ORM 是多层体系的

  • ORM 里面需求去办理多个关联和映射,需求消耗资源
  • 需求咱们学习新知识,增加学习成本
  • 会发生依赖,长时间不用 sql,慢慢的可能你就不会完好的 sql 了
  • 稍不留意可能就会写出低功能的代码
  • … 等等,欢迎弥补

如何去考虑是否要运用 ORM?

那么咱们知道了 ORM 的优劣,那么咱们是否要去选择并运用它呢?

依据咱们实践项意图需求来定,假如项目比较大,对功能要求较高,那么仍是不要运用了

假如项目不大,并且有许多简单的,重复的,低效的数据操作,那么仍是能够运用的,运用起来确实非常便利,便利到让你忘掉 sql

总的来说,要仍是不要,是个问题,假如是你,你会怎么选?

欢迎点赞,重视,收藏

朋友们,你的支撑和鼓舞,是我坚持分享,进步质量的动力

我们要不要使用 ORM?

技能是开放的,咱们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

我是阿兵云原生,欢迎点赞重视收藏,下次见~

文中提到的技能点,感兴趣的能够检查这些文章:

  • GO web 开发 实战三,数据库预处理
  • GO web 开发 实战二,数据库相关
  • GO 言语 Web 开发实战一