Golang开发汇总

版本信息:

go版本:go1.17.4 windows/amd64

gorm版本:v1.22.4

mysql版本:8.0

go官网:go.dev

gorm官网:GORM - The fantastic ORM library for Golang, aims to be developer friendly.

1.windows下交叉编译Linux环境下的可执行文件。

不管是用powershell还是cmd,都需要使用管理员打开,才能正常编译。如果你是使用visual studio code,vs code终端默认使用的是powershell,如下:

需要使用下面的命令先设置环境变量:

// 要带上$
$Env:GOOS = "linux"
$Env:GOARCH = "amd64"

 然后在项目目录下执行:

go build

就会自动生成一个不带扩展名的可执行文件,将该文件放到Linux上,直接执行就可以了,可能会报一个错误:Permission Denied,这个是因为权限不够导致的,给一个权限就行了,比如:

chmod 777 ./gotest

当然权限你可以自己更细地去控制。

如果是cmd,那么执行下面的命令:

set GOOS = linux
set GOARCH = amd64

然后再执行build命令就可以了。

2.使用gorm连接数据库。gorm是中国开发者开发的一个插件,在go官方的文档里有推荐。这里以mysql为例介绍下它的使用方法。引入gorm:

import (
	"gorm.io/gorm"
)

然后在项目根目录下使用命令下载依赖:

go get .

依赖下载好之后,创建一个struct:

type Product struct {
	gorm.Model

	Code  string
	Price uint
}

继承自gorm.Model,其中Model的定义查看go源码可以发现如下:

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

这里的命名方式一律采用大写开头的驼峰式命名。创建好结构体之后,使用下面的方法连接mysql数据库:

dsn := "root:123@tcp(127.0.0.1:3306)/my_schema?
charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.New(mysql.Config{
    DSN:                       dsn,   // DSN data source name
    DefaultStringSize:         256,   // string 类型字段的默认长度
    DisableDatetimePrecision:  true,  // 禁用 datetime 精度,MySQL 5.6 之前的数据库不支持
    DontSupportRenameIndex:    true,  // 重命名索引时采用删除并新建的方式,MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引
    DontSupportRenameColumn:   true,  // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列
    SkipInitializeWithVersion: false, // 根据当前 MySQL 版本自动配置
	}), &gorm.Config{})

if err != nil {
    panic("failed to connect database")
}

连接好数据库之后,如果是代码先的方式,那么需要迁移数据库,方法如下:

	// 迁移 schema
	db.AutoMigrate(&Product{})

执行完该句代码后,查看数据库,会发现多了一张products表,这里gorm给表名自动加了s,同时列名也以大写字母位置使用下划线隔开的风格为标准,这是符合mysql的命名规范的,如下:

如果该数据库已经存在,则是根据结构体的情况决定是否更新数据表,如果结构体未发生变化,则不需要更新,如果发生了变化,且table表结构未及时更新,那么调用AutoMigrate方法就会触发数据库更新。创建好表之后,则是增删改查数据,具体操作如下:

	// Create
	db.Create(&Product{Code: "D42", Price: 100})

	// Read
	var product Product
	db.First(&product, 1)                 // 根据整形主键查找
	db.First(&product, "code = ?", "D42") // 查找 code 字段值为 D42 的记录

	// Update - 将 product 的 price 更新为 200
	db.Model(&product).Update("Price", 200)
	// Update - 更新多个字段
	db.Model(&product).Updates(Product{Price: 200, Code: "F42"}) // 仅更新非零值字段
	db.Model(&product).Updates(map[string]interface{}{"Price": 200, "Code": "F42"})

	// Delete - 删除 product
    // 这里的删除是将delete_at字段的值设置为当前的值
	db.Delete(&product, 1)

3.gorm数据库先操作数据库。前面我们用gorm操作数据库,是采用代码先的方式,所谓代码先就是先有代码,后有数据库结构,实际上大多数场景下,这个方式都是不合适的,为了更好的管理数据库,我们一般都是自己设计数据库结构,然后再用orm连接数据库进行操作。

创建一张user_table表,如下:

创建struct同时继承接口TableName:

type User struct {
	Uid          uint `gorm:"primarykey;column:id"`
	UserName     string
	Telephone    string
	Nickname     string
	PW string `gorm:"column:password"`
}

func (User) TableName() string {
	return "user_table"
}

id在数据库中是自增的,因此在插入数据的时候,不需要给id的值,插入数据方法如下:

data := User{UserName: "test", Telephone: "12345678912",
    Nickname: "测试", PW: "sdfjklsjfalk"}
db.Create(&data)

插入数据后,生成的自增id会自动填充User的uid,此时struct的uid就是数据库返回的自增id

如果想在指定的列插入,如下,只插入UserName和Telephone两个值:

data := User{UserName: "test", Telephone: "12345678912",
    Nickname: "测试", PW: "sdfjklsjfalk"}
db.Select("UserName", "Telephone").Create(&data)

4.引用其他项目的模块。创建两个目录,一个叫go-lib,一个叫go-test。

在go-lib目录下执行:

go mod init go-lib

在go-test目录下执行:

go mod init go-test

再分别在两个目录下创建子目录help,在go-test目录下创建文件main.go,如下:

此时的go-test和go-lib相当于两个项目。

分别在两个两个help目录下创建help.go文件,其中go-lib里面的内容如下:

package help

import "fmt"

func SayHello() {
	fmt.Println("hello from go-lib")
}

go-test里面的内容如下:

package help

import "fmt"

func SayHello() {
	fmt.Println("hello from go-test")
}

目录结构如下:

 现在我们希望在go-test项目里调用go-lib项目的某个方法,比如在go-test的main方法里面调用go-lib的help包下的SayHello方法,代码如下:

package main

import (
	"go-lib/help"
)

func main() {
	help.SayHello()
}

这个时候如果编译go-test会报:main.go:4:2: package go-lib/help is not in GOROOT的错误,这是因为找不到go-lib/help这个包。在go-test的go.mod文件里面添加如下代码:

module go-test

go 1.17

// 添加如下内容
// 描述依赖的package名,v0.0.0用于网上版本的版本号,本地模式也要有
require go-lib v0.0.0
// 描述依赖的package所在的目录,../go-lib就是路径
replace go-lib => ../go-lib

再使用

go run .

就可以正常编译并运行了,运行结果如下:

 这样我们就实现了调用不同项目的包里面的函数。

这里是如何区分两个help包的呢,关键在于引用代码使用的module名,也就是下面的go-lib:

import (
	"go-lib/help"
)

如果把go-lib改成go-test,那么引用的就是当前项目的help包,比如下面这样:

package main

import (
	"go-test/help"
)

func main() {
	help.SayHello()
}

运行结果如下:

 所以我们最初使用的命令:

go mod init go-lib
go mod init go-test

其实定义的是模块名,以方便其他的项目引用。这个命令并不会创建任何额外的目录,只会在当前目录下创建一个go.mod文件。go.mod文件规定了go的版本,和当前项目的module的名称。

5.上例中,我们是在本地引用电脑里其他项目的包,这里说一下如何将go-lib发布到github并通过远程下载的方式在本地项目里面引用。

在github创建一个public的项目,名字叫go-lib。将本地的go-lib上传到刚创建的仓库,这里上传方法不再介绍,创建好仓库后,github会有上传步骤。上传前先做一下修改,将go.mod文件里面的module名字改为你的github仓库所在的路径,比如:

module github.com/DaiAnpeng/go-lib

go 1.17

让引用稍微复杂一些,这里多添加一个模块叫common,help最终引用的是common的sayhello方法,如下:

 common.go的代码如下:

package common

import "fmt"

func SayHello() {
	fmt.Println("hello from go-lib")
}

help.go的代码改为:

package help

import "github.com/DaiAnpeng/go-lib/common"

func SayHello() {
	common.SayHello()
}

修改好之后,将项目推送到github,这里是我推送的代码示例:https://github.com/DaiAnpeng/go-lib

推送好之后,就可以在任意的项目里面通过:

import (
	"github.com/DaiAnpeng/go-lib/help"
)

引用该项目里面的包了。

随便新建一个项目叫go-publish-study,使用go mod初始化,然后添加main函数,内容如下:

package main

import "github.com/DaiAnpeng/go-lib/help"

func main() {
	help.SayHello()
}

项目的目录如下:

 这里的go.sum是执行下面的命令自动创建的:

go get .

然后执行:

go run .

结果如下:

 这样,我们就成功发布了自己的开源项目。

6.go发布包的版本控制。

关于版本控制这块儿的官方文档连接:Go Modules: v2 and Beyond - The Go Programming Language

关于Semantic Versioning的介绍连接:Semantic Versioning 2.0.0 | Semantic Versioning

go的版本控制是遵循Semantic Versioning协议的。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值