Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

最近梳理项目结构的时候,对于Go中项目执行流程有点模糊,因此有了本文的诞生方便巩固复习

我们知道整个Go项目只能有一个全局的main()函数,但是Go项目可以有多个不同的package,每一个package下都可以有很多go文件,每一个go文件可以导入其他package,并且每一个go文件可以包含自己的常量定义,全局变量,init()以及其他函数。总结下来,一个Go程序中通常由导入的包,常量,变量,init(),其他函数,main()构成,那么具体的执行流程是怎样的呢?

注意不可以因为导入包造成循环依赖

正常的执行流程:

  1. 首先进入main函数所在的go文件,假设为main.go
    1. 执行 main.go 中的 import 语句,然后进入到其他的pkg中,
      1. 重复我们进入main.go中的类似流程:首先执行import导包,然后定义常量和全局变量并执行init
    2. 执行const定义的常量
    3. 执行var定义的变量
    4. 执行init()对应的初始化函数
    5. 执行main()启动程序

注意点:

  1. 同一个包下面的多个go文件,如果每一个go文件中都有一个init函数,那么执行顺序就是go文件的导入顺序,并且同包下的不同 go 文件,按照文件名“从小到大”排序顺序执行
  2. 其他的包只有被 main 包 import 才会执行,按照 import 的先后顺序执行,也就是按照 main 包中 import 的顺序调用其包中的 init() 函数
  3. 一个包被其它多个包 import,但只能被初始化一次
  4. 对同一个 go 文件的 init( ) 调用顺序是从上到下的
  5. 在同一个 package 中,可以多个文件中定义 init 方法
  6. 在同一个 go 文件中,可以重复定义 init 方法
  7. 在同一个 package 中,不同文件中的 init 方法的执行按照文件名先后执行各个文件中的 init 方法
  8. 所有 init 函数都在同⼀个 goroutine 内执⾏。 所有 init 函数结束后才会执⾏ main.main 函数。

参考文章

  1. Go语言的执行顺序(转)

LVS84L

gorm的使用

安装

  1. 使用指令进行安装:go get github.com/jinzhu/gorm

DDL操作

前提

  1. 新建一个数据库gorm_project
  2. 指定使用Utf8编码

数据库连接

对应的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package main

import (
"fmt"
"github.com/jinzhu/gorm"
//_ "github.com/go-sql-driver/mysql" //导入驱动方式一
_ "github.com/jinzhu/gorm/dialects/mysql" //导入驱动方式二,前面加上_表示不去校验用没用
)

/**
* @Author: yirufeng
* @Date: 2021/3/22 10:00 下午
* @Desc:
**/

var (
MYSQL_USERNAME = "root"
MYSQL_PASSWORD = "qwertyasdfgh"
MYSQL_IP = "81.69.26.201"
MYSQL_PORT = "3306"
MYSQL_DATABASE = "gorm_project"
)

func main() {

//parseTime用来处理time.Time类型的数据
//loc=Local表示根据本地时区走
//连接信息:用户名:密码@tcp(ip:port)/数据库名称?charset=utf8&parseTime=True&loc=Local
connInfo := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8&parseTime=True&loc=Local",
MYSQL_USERNAME, MYSQL_PASSWORD, MYSQL_IP, MYSQL_PORT, MYSQL_DATABASE)

//使用open来连接数据库
//第一个参数是dialect也就是指定数据库的类型
//第二个参数是连接信息
db, err := gorm.Open("mysql", connInfo)
if err != nil {
panic(err)
}

defer db.Close() //关闭空闲的连接
}

问题描述

使用Golang操作Mysql,插入一条记录后发现新插入的时间比当前时间早了8个小时。

  1. 使用go-sql-driver来连接mysql数据库,获取的时区默认是UTC +0的,与本地的东八区是有区别,在业务处理中会出现问题

  2. 获取mysql中的日期,是string类型,需要在代码中用time.Parse进行转化

解决方案

在连接的dataSourceName中加上parseTime=Trueloc=local。此处的local可以更换为具体的时区(Asia/Shanghai)

修改之前的dataSourceName
1
2
3
dataBaseSource := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s", 
MysqlUser, MysqlPassword, MysqlHost, MysqlPort, MysqlDatabase, MysqlCharset)
conn, _ := sql.Open("mysql", dataBaseSource)
修改后的dataSourceName
1
2
3
dataBaseSource := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s&loc=Local&parseTime=true", 
MysqlUser, MysqlPassword, MysqlHost, MysqlPort, MysqlDatabase, MysqlCharset)
conn, _ := sql.Open("mysql", dataBaseSource)