Go Web 编程--应用ORM

栏目: IT技术 · 发布时间: 4年前

内容简介:这篇文章我们主要探究下面这些内容。gorm的基本用法如何管理ORM的使用
Go Web 编程--应用ORM

这篇文章我们主要探究下面这些内容。

gorm的基本用法

如何管理ORM的使用

如何合理规划项目目录结构

安装gorm包

gorm是一个出色的,对开发人员友好的 Golang ORM 库,其支持的特性包括:

全特性 ORM (几乎包含所有特性)

模型关联 (一对一, 一对多,一对多(反向), 多对多, 多态关联)

钩子 (Before/After Create/Save/Update/Delete/Find)

预加载

事务

复合主键

SQL 构造器

自动迁移

日志

使用如下命令进行安装:

go get -u github.com/jinzhu/gorm

将gorm加入项目中

规划数据模型目录结构

我们在项目根目录下新建如下目录:

http_demo
|
└───model
│  └───dao
│  │  init.go
│  └───────table
│          │  user.go

Go 中包以目录的形式来组织,所以model包中存放所有数据模型,dao代表数据访问对象,存放数据库CRUD方法的封装,其中的init.go存放dao包的初始化函数主要是用来在加载包后连接上数据库。table包里放与数据表对应的模型定义(使用 ORM 之前要先定义模型与数据库中的表对应),在示例里我们会定义一个User模型放在user.go文件中。

规划完目录后就可以在各部分写相应的代码了,首先来看使用gorm连接数据库。

连接数据库

我们在dao包的init.go中加入包的初始化逻辑进行数据库连接,初始化函数会在dao包第一次被导入时执行,由于gorm文档连接数据库的例子太简单,参考价值不大,我们根据项目需要做些简单封装,init.go中的代码如下所示:

package dao
import (
  _ "github.com/go-sql-driver/mysql"
  "github.com/jinzhu/gorm"
  "time"
)
var _DB *gorm.DB
func DB() *gorm.DB {
  return _DB
}
func init() {
  _DB = initDB()
}
func initDB() *gorm.DB {
  // In our docker dev environment use
  // db, err := gorm.Open("mysql", "go_web:go_web@tcp(database:3306)/go_web?charset=utf8&parseTime=True&loc=Local")
  db, err := gorm.Open("mysql", "go_web:go_web@tcp(localhost:33063)/go_web?charset=utf8&parseTime=True&loc=Local")
  if err != nil {
      panic(err)
  }
  db.DB().SetMaxOpenConns(100)
  db.DB().SetMaxIdleConns(10)
  db.DB().SetConnMaxLifetime(time.Second * 300)
  if err = db.DB().Ping(); err != nil {
      panic(err)
  }
  return db
}

代码很简单,大家实操的时候根据自己的 MySQL 配置更改代码里面的配置就行了。唯一说明一点的是,如果使用了我们提提供的 Docker 环境,在连接数据库时host要改为database:3306,因为我在容器环境里将MySQL容器的服务名定义成了database,在运行了Go的app容器需要用服务名访问容器网络中的其他容器。关于容器环境的详细配置请大家查看Go Web编程--应用数据库 中的描述。

定义模型

使用模型访问数据库的表之前我们需要先定义对应的模型。我们示例中现在只有一个users表,接下来我们在table包中添加users表的模型定义并放置在user.go文件中。

package table
import "time"
type User struct {
  Id        int64    `gorm:"column:id;primary_key"`
  UserName  string    `gorm:"column:username"`
  Secret    string    `gorm:"column:secret;type:varchar(1000)"`
  CreatedAt time.Time `gorm:"column:created_at"`
  UpdatedAt time.Time `gorm:"column:updated_at"`
}
// TableName sets the insert table name for this struct type
func (m *User) TableName() string {
  return "users"
}

模型 CRUD

关于模型的 CRUD,建议将单个模型的CRUD放在dao包的单个文件中,这样方便以后代码的管理。这里多说一点,建议不要直接用controller或者叫handler包直接访问dao包,而是在中间加一层logic包,把逻辑放在这一层。这样对代码的管理、复用性都有帮助。

因为数据库的 CRUD 有很多种操作,本文的目的是帮助大家快速开始使用gorm所以我就只放简单的 CRUD 做演示了。大家按照这里步骤引入gorm后用到其他的数据库操作了直接去官方文档里查一查就好。

在dao包中新建user.go用来存放User模型的操作方法。

package dao
import "example.com/http_demo/model/dao/table"
func CreateUser(user *table.User) (err error) {
 err = DB().Create(user).Error
 return
}
func GetUserById(userId int64) (user *table.User, err error) {
 user = new(table.User)
 err = DB().Where("id = ?", userId).First(user).Error
 return
}
func GetAllUser() (users []*table.User, err error) {
 err = DB().Find(&users).Error
 return
}
func UpdateUserNameById(userName string, userId int64) (err error) {
 user := new(table.User)
 err = DB().Where("id = ?", userId).First(user).Error
 if err != nil {
 return
 }
 user.UserName = userName
 err = DB().Save(user).Error
 return
}
func DeleteUserById(userId int64) (err error) {
 user := new(table.User)
 err = DB().Where("id = ?", userId).First(user).Error
 if err != nil {
 return
 }
 err = DB().Delete(user).Error
 return
}

验证ORM 方法

经过上面几步的设置后我们就可以在项目里使用gorm访问数据库了,由于我们项目的main goroutine中运行了http服务,所以我们使用测试用例对上面dao包中定义的几个方法进行一下测试。

篇幅原因我就只贴一个GetAllUsers方法的测试用例了:

func TestGetAllUser(t *testing.T) {
 tests := []struct {
 name      string
 wantErr  bool
 }{
 {
 name: "test",
 wantErr: false,
 },
 }
 for _, tt := range tests {
 t.Run(tt.name, func(t *testing.T) {
 gotUsers, err := GetAllUser()
 if (err != nil) != tt.wantErr {
 t.Errorf("GetAllUser() error = %v, wantErr %v", err, tt.wantErr)
 return
 }
 for _, user := range gotUsers {
 log.Info("user: %v", user)
 }
 })
 }
}

运行测试后,可以看到结果:

INFO user: &{1  2020-02-15 14:14:46 +0800 CST 2020-02-15 06:44:17 +0800 CST}
--- PASS: TestGetAllUsers (0.00s)
    --- PASS: TestGetAllUsers/test (0.00s)
PASS
Process finished with exit code 0

重新规划项目目录

引入ORM后,我们项目中的代码就比较多了,都放在根目录下的main包中有点杂乱,所以我们根据各部分的功能和职责对项目目录进行了简单的划分,划分后的目录结构如下:

http_demo
|
└───handler//route handler
|
└───logic//business logic
|
└───middleware
│
└───model
│  └───dao
│  │  init.go
│  └───table
│      │  user.go
└───router// router
|
|  main.go

感觉今天的内容还是挺多的,尤其对于刚入门Go的同学们一定要把今天的代码下载下来实操一遍才能掌握。gorm提供的功能还是很多的,每个功能在官方文档里都有讲解,我们这里就不做过多介绍了。这篇文章的目的主要是让大家能快速入门,同时把ORM相关的代码管理和初始化流程做的规范些,这些组织方式完全可以应用到生产级别的项目中的

作者:kevinyan

链接:https://juejin.im/post/5e4896ef6fb9a07c8334d368


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

奔跑吧 Linux内核

奔跑吧 Linux内核

张天飞 / 人民邮电出版社 / 2017-9-1 / CNY 158.00

本书内容基于Linux4.x内核,主要选取了Linux内核中比较基本和常用的内存管理、进程管理、并发与同步,以及中断管理这4个内核模块进行讲述。全书共分为6章,依次介绍了ARM体系结构、Linux内存管理、进程调度管理、并发与同步、中断管理、内核调试技巧等内容。本书的每节内容都是一个Linux内核的话题或者技术点,读者可以根据每小节前的问题进行思考,进而围绕问题进行内核源代码的分析。 本书内......一起来看看 《奔跑吧 Linux内核》 这本书的介绍吧!

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具