beego orm根据模型自动生成mysql数据表

语言: CN / TW / HK

前言:

有时候我们不行通过手动的方式写sql语句来建表,而是通过程序的方式自动建表,例如php的laravel框架的迁移文件就是一个典型的实线,那么GO语言的beego orm框架是否有类似的解决方案呢?本文章主要来研究一下这个问题。在阅读本编文章之前,我们假设本地已经装有MySQL数据库或者已经有可远程连接的MySQL

实践步骤

1、新建一个工程,工程名为:dblearn (可自定义)

2、生成工程的go.mod

# 在dblearn目录下打开cmd命令行 执行如下命令:
go mod init dblearn

3、编写工程的main.go

package main

import (
	"fmt"
	"os"

	"github.com/beego/beego/v2/client/orm"
	_ "github.com/go-sql-driver/mysql"

	_ "dblearn/models"
)

func init() {
	// 链接数据库
	dbUsername := "root"
	dbPassword := ""
	host := "127.0.0.1"
	port := 3306
	dbName := "demo"

	dataSource := fmt.Sprintf("%s:%[email protected](%s:%d)/%s?charset=utf8", dbUsername, dbPassword, host, port, dbName)
	if err := orm.RegisterDataBase("default", "mysql", dataSource); err != nil {
		fmt.Println("conn mysql db so give up. err:", err)
		os.Exit(1)
	}

	// 根据模型创建数据库(执行数据库迁移文件)
	// 第二个参数:最容易出错的地方,如果值为ture时,表已经存在并且表中有值的情况下,它会先删除原来的表,然后重新创建,这样原表中的数据就全部丢失了。
	// 第三个参数:是否输出建表的sql日志 true:输出 false:不输出
	if err := orm.RunSyncdb("default", false, true); err != nil {
		fmt.Println("orm.RunSyncdb err:", err)
	}
}

func main() {

}

4、新建一个models目录

5、编写models/users.go文件

package models

import (
	"time"

	"github.com/beego/beego/v2/client/orm"
)

type User struct {
	Id        int       `orm:"auto;pk"`                                  // auto:当 Field 类型为 int, int32, int64, uint, uint32, uint64 时,可以设置字段为自增健;pk:主键
	Username  string    `orm:"size(32);type(char)"`                      // 多个设置间使用 ; 分隔,设置的值如果是多个,使用 , 分隔。设置 - 即可忽略 struct 中的字段
	Mobile    string    `orm:"unique"`                                   // 为单个字段增加 unique 键
	Password  string    `orm:"column(pwd)"`                              // 为字段设置 数据库 字段的名称
	Gender    int       `orm:"index;default(1);description(性别:1 男 2 女)"` // index:为单个字段设置普通索引;default:设置默认值,description:字段注释
	Avatar    string    `orm:"null;size(100)"`                           // 数据库表默认为 NOT NULL,设置 null 代表 ALLOW NULL;size:string 类型字段默认为 varchar(255),设置 size 以后,db type 将使用 varchar(size),如果想char类型则加type(char)
	Money     float64   `orm:"digits(8);decimals(2)"`                    // 设置 float32, float64 类型的浮点精度,总长度 8 小数点后 2 位 eg: 999999.99
	CreatedAt time.Time `orm:"auto_now_add;type(datetime)"`              // auto_now_add 第一次保存时才设置时间
	UpdatedAt time.Time `orm:"auto_now;type(datetime)"`                  // auto_now 每次 model 保存时都会对时间自动更新;type:设置为 date 时,time.Time 字段的对应 db 类型使用 date,设置为 datetime 时,time.Time 字段的对应 db 类型使用 datetime
}

func init() {
	orm.RegisterModel(new(User))
}

// 自定义表名 (默认模型名小写)
func (u *User) TableName() string {
	return "users"
}

// 设置引擎为 INNODB
func (u *User) TableEngine() string {
	return "INNODB"
}

// 联合唯一键
func (u *User) TableUnique() [][]string {
	return [][]string{
		[]string{"Mobile", "Username"},
	}
}

// 普通联合 索引
func (u *User) TableIndex() [][]string {
	return [][]string{
		[]string{"Gender", "Username"},
	}
}

6、运行项目,可看到如下日志输出:

总结:

通过以上项目我们已经知道通过模型的orm tag可以自定义数据表的字段,且通过orm.RunSyncdb触发自动建表。但是这种方式有明显的缺点:1.只支持首次建表,不支持字段更新的操作,这种方式显然不能满足商业化应用。那怎么才能让orm做到像laravel一样的效果呢?下一篇文章我们再来介绍

分享到: