SQL的创建语句转化成Golang的ORM结构体(struct)

在Golang的Web编程中,有时候我们创建了一个SQL的表,需要编写对应的结构体的代码。这是一项繁琐无聊的工作。本文介绍一种自动将创建表格的SQL语句转换成Golang的ORM结构体的代码,从而提高编程效率。代码来自于我的Github。

例子

例子:下面是一个创建user表的sql语句

CREATE TABLE `USER`(
    `id` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'primary key',
    `ip_address` INT  NOT NULL DEFAULT 0 COMMENT 'ip_address',
    `nickname`    VARCHAR(128) NOT NULL DEFAULT '' COMMENT 'user note',
    `description` VARCHAR(256) NOT NULL DEFAULT '' COMMENT 'user description',
    `creator_email` VARCHAR(64) NOT NULL DEFAULT '' COMMENT 'creator email',
    `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'create time',
    `deleted_at` TIMESTAMP NULL DEFAULT NULL COMMENT 'delete time',
    PRIMARY KEY(`id`)
)ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='user table';

函数SqlToGo将其转化成下面的代码。其中,包名是可以选择的。

package sql_to_go_test

import (
	"time"
)

type USER struct {
	Id           uint      `comment:"primary key"`
	IpAddress    int       `comment:"ip_address"`
	Nickname     string    `comment:"user note"`
	Description  string    `comment:"user description"`
	CreatorEmail string    `comment:"creator email"`
	CreatedAt    time.Time `comment:"create time"`
	DeletedAt    time.Time `comment:"delete time"`
}

基本思想

SqlToGo主要做了2件事。

  1. 解析sql语句,这里使用第三方包github.com/xwb1989/sqlparser去解析,获取表的名字,字段名,字段类型,字段的注释。
  2. 将解析的MySQL数据类型转化为Golang的数据类型,并且将以上的数据,做字符串的拼接,拼接成一个Golang的struct文件。
    MySQL与Golang的类型对应映射如下.
var sqlTypeMap = map[string]string{
	"int":                "int",
	"integer":            "int",
	"tinyint":            "int8",
	"smallint":           "int16",
	"mediumint":          "int32",
	"bigint":             "int64",
	"int unsigned":       "uint",
	"integer unsigned":   "uint",
	"tinyint unsigned":   "uint8",
	"smallint unsigned":  "uint16",
	"mediumint unsigned": "uint32",
	"bigint unsigned":    "uint64",
	"bit":                "byte",
	"bool":               "bool",
	"enum":               "string",
	"set":                "string",
	"varchar":            "string",
	"char":               "string",
	"tinytext":           "string",
	"mediumtext":         "string",
	"text":               "string",
	"longtext":           "string",
	"blob":               "string",
	"tinyblob":           "string",
	"mediumblob":         "string",
	"longblob":           "string",
	"date":               "time.Time",
	"datetime":           "time.Time",
	"timestamp":          "time.Time",
	"time":               "time.Time",
	"float":              "float64",
	"double":             "float64",
	"decimal":            "float64",
	"binary":             "string",
	"varbinary":          "string",
}

下划线命名改为驼峰式命名

在SQL的命名规范中,字段的命名一般都是下划线分隔的,例如ip_address。而Golang的struct的字段的命名是驼峰式的。
SqlToGo会将其字段命名转化为驼峰式的。对应的转化代码如下。
基本思想是,扫描字符串,如果遇到字符_,并且_的字符是一个英文字母,将将其转化为大写,并且忽略这个_

// In sql, table name often is snake_case
// In Go, struct name often is camel case
func snakeCaseToCamel(str string) string {
	builder := strings.Builder{}
	index := 0
	if str[0] >= 'a' && str[0] <= 'z' {
		builder.WriteByte(str[0] - ('a' - 'A'))
		index = 1
	}
	for i := index; i < len(str); i++ {
		if str[i] == '_' && i+1 < len(str) {
			if str[i+1] >= 'a' && str[i+1] <= 'z' {
				builder.WriteByte(str[i+1] - ('a' - 'A'))
				i++
				continue
			}
		}
		builder.WriteByte(str[i])
	}
	return builder.String()
}

总结

经过SQL语句的解析,转换,字符串的拼接,就将一个SQL语句转化成Golang的结构体了。

你可能感兴趣的:(golang,go,mysql,字符串)