文章

Sqlx&Xorm&Gorm

Sqlx

Go语言连接mysql

安装包

go get "github.com/go-sql-driver/mysql"
go get "github.com/jmoiron/sqlx"

⚠️如果下载出现超时现象

image-20230111003336357

可以尝试看一下环境的代理

go env

找到

GOPROXY="https://goproxy.cn,direct"

百度上有很多,我是按照如下进行配置

//mac
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn

然后就可以进行下载啦参考文档

创建数据库表(mysql暂无教程,后续补充):

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增主键',
  `userid` int(11) NULL DEFAULT NULL COMMENT '用户id',
  `username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户名',
  `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户密码',
  `avatar` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户头像',
  `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
package main

import (
   "fmt"
   _ "github.com/go-sql-driver/mysql"
   "github.com/jmoiron/sqlx"
)

func main() {
   mysqlDB := connectMySQL()
   defer mysqlDB.Close()
}

// 准备数据库的连接信息
var (
   userName  string = "root"
   passWord  string = "root"
   ipAddress string = "127.0.0.1"
   port      string = "3306"
   dbName    string = "go_test"
   charset   string = "utf8mb4"
)

// 连接mysql数据库
//
//root:123456@tcp(127.0.0.1:3306)/go_test?charset=utf8mb4
func connectMySQL() *sqlx.DB {
   dbstr := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s", userName, passWord, ipAddress, port, dbName, charset)
   DB, err := sqlx.Open("mysql", dbstr)
   fmt.Println(err)
   ping(DB)
   return DB
}

// 测试mysql是否连接成功
func ping(DB *sqlx.DB) {
   err := DB.Ping()
   if err != nil {
      fmt.Println("ping failed")
   } else {
      fmt.Println("ping succes")
   }
}

image-20230109211956958

Exce增删改

insertSQL := "insert into user(userid,username,password,avatar,create_time,update_time) values (?,?,?,?,?,?)"
result, err := mysqlDB.Exec(insertSQL, 10000, "yama", "123456", "yama.png", "2023-01-01 11:11:11", "2023-01-01 11:11:11")
if err != nil {
   fmt.Println("数据插入失败", err)
   return
}
id, _ := result.LastInsertId()
fmt.Println("数据出入成功,last ID:", id)

deleteSQL := "delete from user where id = 8"
result3, err := mysqlDB.Exec(deleteSQL)
rowNum, _ = result3.RowsAffected() //收到影响的行数
fmt.Println("删除成功,affected rows:", rowNum)

updateSQL := "update user set username = 'jiang' where id = 7"
result2, err := mysqlDB.Exec(updateSQL)
rowNum, _ := result2.RowsAffected() //收到影响的行数
fmt.Println("更新成功,affected rows:", rowNum)

Query查询

Query()方法返回的是一个sql.Rows类型的结果集,也可以用来查询多个字段的数据,不过需要定义多个字段的变量进行接收,迭代后者的Next()方法,然后使用Scan()方法给对应类型变量赋值,以便取出结果,最后再把结果集关闭(释放连接)

package main

import (
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"github.com/jmoiron/sqlx"
)

// 准备数据库的连接信息
var (
	userName  string = "root"
	passWord  string = "root"
	ipAddress string = "127.0.0.1"
	port      string = "3306"
	dbName    string = "go_test"
	charset   string = "utf8mb4"
)

// 连接mysql数据库
//
//root:123456@tcp(127.0.0.1:3306)/go_test?charset=utf8mb4
func connectMySQL() *sqlx.DB {
	dbstr := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s", userName, passWord, ipAddress, port, dbName, charset)
	DB, err := sqlx.Open("mysql", dbstr)
	fmt.Println(err)
	ping(DB)
	return DB
}

// 测试mysql是否连接成功
func ping(DB *sqlx.DB) {
	err := DB.Ping()
	if err != nil {
		fmt.Println("ping failed")
	} else {
		fmt.Println("ping succes")
	}
}
func testQuery(mysqlDB *sqlx.DB) {
   querySQL := "select * from user"
   rows, err := mysqlDB.Query(querySQL)
   if err != nil {
      fmt.Println(err)
      return
   }
   //fmt.Println(rows)
   //rows
   //rows.Next()
   for rows.Next() {
      var id, userid int
      var username, password, avatar, create_time, update_time string
      //rows.Scan()
      rows.Scan(&id, &userid, &username, &password, &avatar, &create_time, &update_time)
      fmt.Println(id, userid, username, password, avatar, create_time, update_time)

   }
   rows.Close()
}
func main() {
	mysqlDB := connectMySQL()
	defer mysqlDB.Close()
	testQuery(mysqlDB)
}

image-20230111010515109

Get方法

func (db *DB) Get(dest interface{},query string,args ... interface) error

将查询到的一条记录,保存到结构体

说明:结构体的字段首字母必须大写

Select方法

func (db *DB) Select(dest interface{},query string,args ... interface) error

将查询的多条记录,保存到结构体的切片中

说明:结构体的字段名首字母必须大写

package main

import (
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"github.com/jmoiron/sqlx"
)

// 准备数据库的连接信息
var (
	userName  string = "root"
	passWord  string = "root"
	ipAddress string = "127.0.0.1"
	port      string = "3306"
	dbName    string = "go_test"
	charset   string = "utf8mb4"
)

// 连接mysql数据库
//
//root:123456@tcp(127.0.0.1:3306)/go_test?charset=utf8mb4
func connectMySQL() *sqlx.DB {
	dbstr := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s", userName, passWord, ipAddress, port, dbName, charset)
	DB, err := sqlx.Open("mysql", dbstr)
	fmt.Println(err)
	ping(DB)
	return DB
}

// 测试mysql是否连接成功
func ping(DB *sqlx.DB) {
	err := DB.Ping()
	if err != nil {
		fmt.Println("ping failed")
	} else {
		fmt.Println("ping succes")
	}
}
func main() {
   mysqlDB := connectMySQL()
   defer mysqlDB.Close()
   //testExec(mysqlDB)
   //testQuery(mysqlDB)

   type user struct {
      //userid,username,password,avatar,create_time,update_time
      Id          int    `db:"id"`
      UserId      int    `db."userid"`
      UserName    string `db."username"`
      Password    string `db."password"`
      Avatar      string `db."avatar"`
      Create_time string `db."create_time"`
      Update_time string `db."update_time"`
   }
   //var userData *user 查找单行数据
   userData := new(user)
   mysqlDB.Get(userData, "select * from user where id = 10")
   fmt.Println(userData)

   var userSlice []user
   err := mysqlDB.Select(&userSlice, "select * from user")
   if err != nil {
      fmt.Println(err)
      return
   }
   for i := range userSlice {
      fmt.Println(userSlice[i])
   }
}

image-20230111015024551

连接池

连接池说明

只用sqlx.Open()函数创建连接池,此时只是初始化了连接池,并没有连接数据库,连接都是惰性的,只有调用sqlx.DB的方法时,此时才真正用到了连接,连接池才会去创建连接,连接池很重要,它直接影响着你的程序行为

连接池的工作原理:

当调用sqlx.DB的方法时,会首先去向连接池请求要一个数据库连接,如果连接池有空闲的连接,则返回给方法中使用,否则连接池将创建一个新的连接给到方法中使用;一旦将数据库连接给到了方法中,连接就属于了方法了。方法执行完毕后,要不把连接所属权还给连接池,要不传递给下一个需要数据库连接的方法中,最后都使用完将连接释放回到连接池中。

连接池配置

DB.SetMaxldle(n int)设置连接池中的保持连接的最大连接数。默认也是0,表示连接池不会保持数据库连接的状态:即当连接释放回到连接池的时候,连接将会被关闭。这会导致连接再连接池中频繁的关闭和创建,我们可以设置以后哥合理的值。

DB.SetMaxOpenConns(n int)设置打开数据库的最大连接数。包含正在使用的连接和连接池的连接。如果你的方法调用需要用到一个连接,并且连接池已经没有了连接或者连接数达到了最大连接数。此时的方法调用将会被block,知道有可用的连接才会返回。设置这个值可以避免并发高导致连接mysql出现too many connection的错误。该函数的默认设置是0,表示无限制

DB.SetConnMaxLifetime(time.Duration)设置连接可以被使用的最长有效时间,如果过期,连接将被拒绝

数据库连接重试次数

sqlx中的方法帮我们做了很多事情,不用考虑连接失败的情况,当调用方法进行数据库操作的时候,如果连接失败,sqlx中的方法会帮我们处理,它会自动连接2次

其他的方法中也有这样的处理,代码中变量maxBadConnRetries小时如果连接失败尝试的次数,默认是2

xorm

xorm是一个简单而强大的Go语言ORM库,通过它可以使数据库操作非常简单

官网:https://xorm.io/

中文文档:https://gitea.com/xorm/xorm/src/branch/master/README_CN.md

特性

  • 支持Struct和数据库表之间的灵活映射,并支持自动同步
  • 事务支持
  • 同时支持原始SQL语句和ORM操作的混合执行
  • 使用连写来简化调用
  • 支持使用ID, In, Where, Limit, Join, Having, Table, SQL, Cols等函数和结构体等方式作为条件
  • 支持级联加载Struct
  • Schema支持(仅Postgres
  • 支持缓存
  • 通过 xorm.io/reverse 支持根据数据库自动生成 xorm 结构体
  • 支持记录版本(即乐观锁)
  • 通过 xorm.io/builder 内置SQL Builder支持
  • 上下文缓存支持
  • 支持日志上下文

安装

go get xorm.io/xorm

同步结构体到数据库

  1. 创建引擎,driverName,dataSourceName和database/sql 接口相同
  2. 定义一个和标同步的结构体,并且自动同步结构体到数据库
package main

import (
   "fmt"
   _ "github.com/go-sql-driver/mysql"
   "time"
   "xorm.io/xorm"
)

func main() {
   var (
      userName  string = "root"
      passWord  string = "root"
      ipAddress string = "127.0.0.1"
      port      string = "3306"
      dbName    string = "go_test"
      charset   string = "utf8mb4"
   )
   dataSourceName := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s", userName, passWord, ipAddress, port, dbName, charset)
   //xorm.NewEngine
   engine, err := xorm.NewEngine("mysql", dataSourceName)
   if err != nil {
      fmt.Println("连接失败", err)
   }
   type User struct {
      Id      int64
      Age     int
      Avatar  string
      Passwd  string    `xorm:"varchar(200)"`
      Created time.Time `xorm:"created"`
      Updated time.Time `xorm:"updated"`
   }
   //engine.Sync
   err = engine.Sync(new(User))
   if err != nil {
      fmt.Println("表结构同步失败", err)
   }
}

image-20230112000201196

数据插入&更新&删除

  • Insert 插入一条或者多条记录
package main

import (
   "fmt"
   _ "github.com/go-sql-driver/mysql"
   "time"
   "xorm.io/xorm"
)

func main() {
   var (
      userName  string = "root"
      passWord  string = "root"
      ipAddress string = "127.0.0.1"
      port      string = "3306"
      dbName    string = "go_test"
      charset   string = "utf8mb4"
   )
   dataSourceName := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s", userName, passWord, ipAddress, port, dbName, charset)

   engine, err := xorm.NewEngine("mysql", dataSourceName)
   if err != nil {
      fmt.Println("连接失败", err)
   }
   type User struct {
      Id      int64
      Name    string
      Age     int
      Passwd  string    `xorm:"varchar(200)"`
      Created time.Time `xorm:"created"`
      Updated time.Time `xorm:"updated"`
   }
   //engine.Insert() 插入 对象,返回值:受影响的行数
   //插入单条数据
   user := User{Id: 11, Name: "yama", Age: 20, Passwd: "123456"}
   n, _ := engine.Insert(&user)
   fmt.Println(n)
   if n >= 1 {
      fmt.Println("数据插入成功")
   }
   //插入多条数据
   user1 := User{Id: 12, Name: "zuo", Age: 22, Passwd: "123456"}
   user2 := User{Id: 13, Name: "zhao", Age: 24, Passwd: "123456"}
   user3 := User{Id: 14, Name: "jiang", Age: 26, Passwd: "123456"}
   n, _ = engine.Insert(&user1, &user2, &user3)
   fmt.Println(n)
   if n >= 1 {
      fmt.Println("数据插入成功")
   }
   var users []User
   users = append(users, User{Id: 15, Name: "tang", Age: 90, Passwd: "123456"})
   users = append(users, User{Id: 16, Name: "jian", Age: 78, Passwd: "123456"})
   n, _ = engine.Insert(&users)
   fmt.Println(n)
   if n >= 1 {
      fmt.Println("数据插入成功")
   }
}
  • Update 更新数据,默认只更新非空和非0的字段
user := User{Name: "updatetest", Age: 10}
n, _ := engine.ID(16).Update(&user)
fmt.Println(n)
  • Delete 删除记录,需要注意,删除必须至少有一个条件,否则会报错
user = User{Name: "tang"}
n, _ = engine.ID(15).Delete(&user)
fmt.Println(n)
  • Exec 执行一个SQL语句
engine.Exec("update user set age = ? where id = ?", 10, 10)

完整代码:

package main

import (
   "fmt"
   _ "github.com/go-sql-driver/mysql"
   "time"
   "xorm.io/xorm"
)

func main() {
   var (
      userName  string = "root"
      passWord  string = "root"
      ipAddress string = "127.0.0.1"
      port      string = "3306"
      dbName    string = "go_test"
      charset   string = "utf8mb4"
   )
   dataSourceName := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s", userName, passWord, ipAddress, port, dbName, charset)

   engine, err := xorm.NewEngine("mysql", dataSourceName)
   if err != nil {
      fmt.Println("连接失败", err)
   }
   type User struct {
      Id      int64
      Name    string
      Age     int
      Passwd  string    `xorm:"varchar(200)"`
      Created time.Time `xorm:"created"`
      Updated time.Time `xorm:"updated"`
   }
   //Update(&user)
   user := User{Name: "updatetest", Age: 10}
   n, _ := engine.ID(16).Update(&user)
   fmt.Println(n)
   //Delete(&user)
   user = User{Name: "tang"}
   n, _ = engine.ID(15).Delete(&user)
   fmt.Println(n)
   engine.Exec("update user set age = ? where id = ?", 10, 10)

}

数据查询

  • Query 最原始的也支持SQL语句查询,返回的结果类型为 []map[string]byte.QueryString 返回 []map[string]stringQueryInterface 返回 []map[string]interface{}
  • Get查询单挑记录
  • Find查询多条记录
  • Count获取记录条数
  • IterateRows根据条件便利数据
package main

import (
   "fmt"
   _ "github.com/go-sql-driver/mysql"
   "time"
   "xorm.io/xorm"
)

func main() {
   var (
      userName  string = "root"
      passWord  string = "root"
      ipAddress string = "127.0.0.1"
      port      string = "3306"
      dbName    string = "go_test"
      charset   string = "utf8mb4"
   )
   dataSourceName := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s", userName, passWord, ipAddress, port, dbName, charset)

   engine, err := xorm.NewEngine("mysql", dataSourceName)
   if err != nil {
      fmt.Println("连接失败", err)
   }
   type User struct {
      Id      int64
      Name    string
      Age     int
      Passwd  string    `xorm:"varchar(200)"`
      Created time.Time `xorm:"created"`
      Updated time.Time `xorm:"updated"`
   }
   //查询
   //result, err := engine.Query("select * from user")
   //fmt.Println(result)
   //result2, err := engine.QueryString("select * from user")
   //fmt.Println(result2)
   //result3, err := engine.QueryInterface("select * from user")
   //fmt.Println(result3)
   //Get SELECT * FROM user LIMIT 1
   user := User{}
   engine.Get(&user)
   fmt.Println(user)

   //指定条件来查询用户
   user1 := User{Name: "yama"}
   engine.Where("name=?", user1.Name).Desc("id").Get(&user1)
   fmt.Println(user1)
   //获取指定字段的值
   var name string
   engine.Table(&user).Where("id=16").Cols("name").Get(&name)
   fmt.Println(name)
   //Find 查询多条记录
   var users []User
   engine.Where("passwd=123456").And("age=20").Limit(10, 0).Find(&users)
   fmt.Println(users)
   //`Count`获取记录条数
   user = User{Passwd: "123456"}
   counts, err := engine.Count(&user)
   fmt.Println(counts)
   //`Iterate`和`Rows`根据条件便利数据
   //engine.Iterate(&User{Passwd: "123456"}, func(idx int, bean interface{}) error {
   // user := bean.(*User)
   // fmt.Println(user)
   // return nil
   //})
   rows, err := engine.Rows(&User{Passwd: "123456"})
   defer rows.Close()
   userBean := new(User)
   for rows.Next() {
      rows.Scan(userBean)
      fmt.Println(userBean)
   }
}

事务

package main

import (
   "fmt"
   _ "github.com/go-sql-driver/mysql"
   "time"
   "xorm.io/xorm"
)

func main() {
   var (
      userName  string = "root"
      passWord  string = "root"
      ipAddress string = "127.0.0.1"
      port      string = "3306"
      dbName    string = "go_test"
      charset   string = "utf8mb4"
   )
   dataSourceName := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s", userName, passWord, ipAddress, port, dbName, charset)

   engine, err := xorm.NewEngine("mysql", dataSourceName)
   if err != nil {
      fmt.Println("连接失败", err)
   }
   type User struct {
      Id      int64
      Name    string
      Age     int
      Passwd  string    `xorm:"varchar(200)"`
      Created time.Time `xorm:"created"`
      Updated time.Time `xorm:"updated"`
   }
   session := engine.NewSession()
   defer session.Close()

   session.Begin()
   defer func() {
      err := recover()
      if err != nil {
         //回滚
         fmt.Println(err)
         fmt.Println("Rollback")
         session.Rollback()
      } else {
         session.Commit()
      }
   }()

   user1 := User{Id: 20, Name: "yama123456", Age: 40, Passwd: "123456789"}
   if _, err := session.Insert(&user1); err != nil {
      panic(err)
   }
   user2 := User{Name: "查不到", Age: 40}
   if _, err := session.Where("id=1000").Update(&user2); err != nil {
      panic(err)
   }
   if _, err := session.Exec("delete from user where name =yama12345"); err != nil {
      panic(err)
   }
}

Gorm

概述

文档地址:https://gorm.io/zh_CN/

官方介绍

  • 全功能 ORM
  • 关联 (拥有一个,拥有多个,属于,多对多,多态,单表继承)
  • Create,Save,Update,Delete,Find 中钩子方法
  • 支持 Preload、Joins 的预加载
  • 事务,嵌套事务,Save Point,Rollback To to Saved Point
  • Context、预编译模式、DryRun 模式
  • 批量插入,FindInBatches,Find/Create with Map,使用 SQL 表达式、Context Valuer 进行 CRUD
  • SQL 构建器,Upsert,锁,Optimizer/Index/Comment Hint,命名参数,子查询
  • 复合主键,索引,约束
  • 自动迁移
  • 自定义 Logger
  • 灵活的可扩展插件 API:Database Resolver(多数据库,读写分离)、Prometheus…
  • 每个特性都经过了测试的重重考验
  • 开发者友好

ORM:对象关系模型映射。(Object Relation Mapping),就是把数据库的记录映射到go到对象的过程中,称之为ORM

安装mysql驱动

go get -u gorm.io/driver/mysql

安装gorm包

go get -u gorm.io/gorm
package main

import (
   "fmt"
   "gorm.io/driver/mysql"
   "gorm.io/gorm"
)

func main() {
   //1.准备数据库参数
   username := "root"
   password := "root"
   host := "127.0.0.1"
   port := 3306
   dbname := "gorm_test"
   dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local",
      username, password, host, port, dbname)
   //2。连接数据库
   db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
   if err != nil {
      panic(err)
   }
   fmt.Println(db)
}

image-20230116224851640

快速入门

Conn.go

package db

import (
   "fmt"
   "gorm.io/driver/mysql"
   "gorm.io/gorm"
)

func DBConnection() *gorm.DB {
   //1.准备数据库参数
   username := "root"
   password := "root"
   host := "127.0.0.1"
   port := 3306
   dbname := "gorm_test"
   dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local",
      username, password, host, port, dbname)
   //2。连接数据库
   db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
   if err != nil {
      panic(err)
   }
   return db
}

02-demo.go

package main

import (
   db2 "go/src/src/main/15_gorm/gorm/db"
   "gorm.io/gorm"
)

// 结构体(模型)
type Product struct {
   gorm.Model
   Code  string
   Price uint
}

func main() {
   db := db2.DBConnection()

   // 注册结构体,自动创建表,自动创建索引,自动修改表
   db.AutoMigrate(&Product{})

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

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

   //// Update - 将 product 的 price 更新为 200
   //db.Debug().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
   db.Debug().Delete(&product, 1)
}

gorm模型定义

概述

文档:https://gorm.io/zh_CN/docs/models.html

ORM框架操作数据库都需要预先定义模型,模型可以理解成数据模型,作为操作数据库的媒介。

比如:

  • 从数据库读取的数据会先保存到预先定义的模型对象,然后我们就可以从模型对象得到我们想要的数据
  • 插入数据到数据库也是先新建一个模型对象,然后把想要保存到数据先保存到模型对象,然后把模型对象保存到数据库
  • 在golang中gorm模型定义是通过struct实现的,这样我们就可以通过gorm库实现struct类型和mysql表数据到映射

模型约定

gorm负责将对模型的读写操作翻译成sql语句,然后gorm再把数据库执行sql语句后返回的结果转化为我们定义的模型对象

gorm模型定义主要就是在struct类型定义的基础上增加字段标签说明实现:假如有个商品表,表结构如下;

type User struct {  
ID           uint  
Name         string  
Email        *string  
Age          uint8  
Birthday     *time.Time  
MemberNumber sql.NullString  
ActivatedAt  sql.NullTime  
CreatedAt    time.Time  
UpdatedAt    time.Time}

约定

GORM倾向于约定于配置默认情况下,GORM使用ID作为主键,使用结构体名的蛇形复数作为表名,字段名的蛇形作为列名,并使用CreatedAt、UpdateAt字段追踪创建、更新时间

如果遵循GORM的约定,就可以少写的配置、代码。如果约定不符合实际要求,GORM允许你配置它们。

package main

import (
   db2 "go/src/src/main/15_gorm/gorm/db"
   "time"
)

type User struct {
   //主键设定,他会自动增长,自动设置成主键,名字必须叫ID
   ID         int64
   UserName   string
   Avatar     string
   Email      string
   Age        uint8
   Amount     float32
   Birthday   time.Time
   CreateTime time.Time
   UpdateTime time.Time
}

func main() {
   //1.获取连接
   db := db2.DBConnection()
   //2.实体的注册
   db.AutoMigrate(&User{})
}

gorm.Model

GORM定义一个gorm.Model结构体,其包括字段ID、CreatedAt、UpdatedAt、DeleteAt

package main

import (
   db2 "go/src/src/main/15_gorm/gorm/db"
   "time"
)

// type User struct {
//    ID         int64
//    UserName   string
//    Avatar     string
//    Email      string
//    Age        uint8
//    Amount     float32
//    Birthday   time.Time
//    CreateTime time.Time
//    UpdateTime time.Time
// }
//
// type User2 struct {
//    gorm.Model
//    UserName   string
//    Avatar     string
//    Email      string
//    Age        uint8
//    Amount     float32
//    Birthday   time.Time
// }
type Account struct {
   ID       int64     `gorm:"primaryKey;column:userid;autoIncrement;comment:'主键'"`
   UserName string    `gorm:"column:username;comment:用户名;type:varchar(100);not null;index"`
   Avatar   string    `gorm:"column:avatar;comment:头像;type:varchar(400);not null"`
   Email    string    `gorm:"column:email;comment:邮箱;type:varchar(80);not null"`
   Age      uint8     `gorm:"column:age;comment:年龄;type:int(3);default:18"`
   Amount   float32   `gorm:"column:amount;comment:余额;precision:10;scale:2;default:0"`
   Birthday time.Time `gorm:"column:birthday;comment:生日;type:date"`
}

func main() {
   //1.获取连接
   db := db2.DBConnection()
   //2.实体的注册
   db.AutoMigrate(&Account{})
}
License:  CC BY 4.0 test