GenToolPlus version 1.0正式版已发布!
版本更新
支持数据库:mysql、postgres、sqlite、sqlserver
可配置生成所有关联关系:一对一(hasone,belongsto),一对多(hasmany),多对多(many2many)
使用提醒
- 本工具在使用之前,需要你在数据库种配置好相关表的基本信息;
- 针对表之间的hasone/belongsto/hasmany关联关系,设置好对应的外键;
- 针对many2many关联关系需要配置好中间链接表,并设置好复合主键;
- 在gentoolplus_config.json配置文件中,只需要配置表的hasone/belongsto/many2many这三种关联关系,其他关联关系默认均为hasmany,不需要在配置文件中配置hasmany关联关系;
- 本工具是基于GORM/GEN的二次开发,使用前需要对GORM和GEN有基本了解,具体可查阅官网资料。
Install
go get -u github.com/essrt/gentoolplus@latest
go install github.com/essrt/gentoolplus
工具使用
在终端下执行:
gentoolplus -c gentoolplus_config.json
参数选项的解释
- -dbDriver 指定数据库引擎(mysql、postgres、sqlite、sqlserver)
- -dbName 数据库名称
- -dsn 用于连接数据库的DSN
- -outPath 指定输出目录(默认 ./dao/query)
- -outFile 指定输出文件(默认 gen.go)
- -c 配置文件路径(默认 ./gentoolplus_config.json),命令行选项的优先级高于配置文件
- -h 帮助文档
注意:如果不使用配置文件,仅使用命令行传入参数的方式运行,必须提供上述所有参数选项(不包括-h)。
配置文件
命令行选项的优先级高于配置文件,同时设置了配置文件的目录和命令行选项,优先以命令行的选项为参数,省略配置文件的配置。
配置文件为json格式
配置文件示例
{
"version": "1.0",
"database": {
"dbDriver": "mysql",
"dbName": "sqltest",
"dsn": "user:pwd@tcp(localhost:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local",
"outPath": "./dao/query",
"outFile": "gentoolplus.go",
"nspname": "public",
"dataMap": {
"tinyint": "int64",
"smallint": "int64",
"mediumint": "int64",
"bigint": "int64",
"int": "int64"
},
"fieldNullable": true,
"fieldCoverable": true,
"fieldSignable": false,
"fieldWithIndexTag": false,
"fieldWithTypeTag": false,
"withUnitTest": false,
"singularTable": true,
"modelPkgPath": "model"
"tables": [
"address",
"company",
"department",
"position",
"staff",
"staff_position",
"workstation"
],
"belongstoTables": {
// 这里表示:staff belongs to company, staff belongs to department,所有跟staff有belongsto关系的表都写在这个数组中。
"staff": [
"company", "department"
],
... // 其他表的belongsto关系
},
"hasoneTables": {
// 这里表示:staff has one address, staff has one workstation,所有跟staff有hasone关系的表都写在这个数组中。
"staff": [
"address", "workstation"
],
... // 其他表的hasone关系
},
"many2manyTables": {
// 中间表:staff_position,关联表:staff、position
"staff_position": [
"staff",
"position"
],
... // 其他表的many2many关系
}
}
}
配置文件详细参数说明
- dbDriver string 指定数据库引擎(mysql、postgres、sqlite、sqlserver),默认值:mysql
- dbName string 数据库名称
- dsn string 用于连接数据库的DSN
- outPath string 指定输出目录(默认值:./dao/query)
- outFile string 指定输出文件(默认值:gen.go)
- nspname string postgres数据库模式名称,默认值:public,如果数据库中的表不在public模式下,需要指定该参数
- dataMap map[string]string 数据库自定义字段的数据类型
- fieldNullable bool 表字段可为 null 值时, 对应结体字段使用指针类型,默认值:false
- fieldCoverable bool 当字段具有默认值时生成指针,以解决无法分配零值的问题,默认值:false
- fieldSignable bool 模型结构体字段的数字类型的符号表示是否与表字段的一致, false指示都用有符号类型,默认值:false
- fieldWithIndexTag bool 生成 gorm 标签的字段索引属性,默认值:false
- fieldWithTypeTag bool 生成 gorm 标签的字段类型属性,默认值:false
- withUnitTest bool 生成单元测试,默认值:false,
- modelPkgPath string 生成模型代码包名称。默认值:model
- singularTable bool 是否使用单数表名,默认值:true
- tables []string 指定要生成的表名,为空时生成数据库中所有表
- belongstoTables map[string][]string 指定表的关联表,生成关联表的查询方法
- hasoneTables map[string][]string 指定表的一对一关联表,生成关联表的查询方法
- many2manyTables map[string][]string 指定表的多对多关联表,生成关联表的查询方法
注:
belongstoTables key:表名(子表名),value:关联表名(主表名)
hasoneTables key:表名(主表名),value:关联表名(子表名)
many2manyTables key:表名(中间表名),value:关联表名(子表名,子表名)
配置注意事项
- 如果配置了tables数组,程序将只处理tables数组中的表及其关联关系,任何不在tables中的表,且跟tables中的表有关联关系的表都不会处理。
- 如果没有配置tables数组,程序将处理数据库中的所有表及其关联关系。
- 如果配置了tables数组,并且belongstoTables、hasoneTables、many2manyTables也有配置,那么belongstoTables、hasoneTables、many2manyTables中的所有表名必须包含在tables数组中,否则会报错。
- 如果没有配置belongstoTables、hasoneTables、many2manyTables,那么数据库中所有设置了外键的表之间的关联关系默认为一对多(hasmany)关系。
- hasmany关联关系不需要再配置文件中配置,如果两个表之间存在关联关系,且不在hasoneTables/belongstoTables/many2manyTables中配置,默认这两个表的关联关系就是hasmany。
参考例子
创建示例表
创建9个数据库表:
address、company、department、language、role、staff_role、staff、user_languages、user
创建表的sql语句:
CREATE TABLE
`address` (
`id` int NOT NULL AUTO_INCREMENT COMMENT 'Primary Key',
`create_time` datetime DEFAULT NULL COMMENT 'Create Time',
`name` varchar(255) DEFAULT NULL,
`user_id` int DEFAULT NULL,
`company_id` int DEFAULT NULL,
`staff_id` int DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `company_id` (`company_id`),
KEY `staff_id` (`staff_id`),
KEY `user_id` (`user_id`),
CONSTRAINT `address_ibfk_2` FOREIGN KEY (`company_id`) REFERENCES `company` (`id`),
CONSTRAINT `address_ibfk_3` FOREIGN KEY (`staff_id`) REFERENCES `staff` (`id`),
CONSTRAINT `address_ibfk_4` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci
CREATE TABLE
`company` (
`id` int NOT NULL AUTO_INCREMENT COMMENT 'Primary Key',
`create_time` datetime DEFAULT NULL COMMENT 'Create Time',
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE = InnoDB AUTO_INCREMENT = 2 DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci
CREATE TABLE
`department` (
`id` int NOT NULL AUTO_INCREMENT COMMENT 'Primary Key',
`create_time` datetime DEFAULT NULL COMMENT 'Create Time',
`name` varchar(255) DEFAULT NULL,
`company_id` int DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `company_id` (`company_id`),
CONSTRAINT `department_ibfk_1` FOREIGN KEY (`company_id`) REFERENCES `company` (`id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci
CREATE TABLE
`language` (
`id` int NOT NULL AUTO_INCREMENT COMMENT 'Primary Key',
`created_at` datetime DEFAULT NULL COMMENT 'Create Time',
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`staff_id` int DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `staff_id` (`staff_id`),
CONSTRAINT `language_ibfk_2` FOREIGN KEY (`staff_id`) REFERENCES `staff` (`id`)
) ENGINE = InnoDB AUTO_INCREMENT = 18 DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci
CREATE TABLE
`role` (
`id` int NOT NULL AUTO_INCREMENT COMMENT 'Primary Key',
`create_time` datetime DEFAULT NULL COMMENT 'Create Time',
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci
CREATE TABLE
`staff` (
`id` int NOT NULL AUTO_INCREMENT COMMENT 'Primary Key',
`create_time` datetime DEFAULT NULL COMMENT 'Create Time',
`name` varchar(255) DEFAULT NULL,
`company_id` int DEFAULT NULL,
`user_id` int DEFAULT NULL,
`department_id` int DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `company_id` (`company_id`),
KEY `user_id` (`user_id`),
KEY `department_id` (`department_id`),
CONSTRAINT `staff_ibfk_1` FOREIGN KEY (`company_id`) REFERENCES `company` (`id`),
CONSTRAINT `staff_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`),
CONSTRAINT `staff_ibfk_3` FOREIGN KEY (`department_id`) REFERENCES `department` (`id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci
CREATE TABLE
`staff_role` (
`staff_id` int NOT NULL,
`role_id` int NOT NULL,
PRIMARY KEY (`staff_id`, `role_id`),
KEY `role_id` (`role_id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci
CREATE TABLE
`user` (
`id` int NOT NULL AUTO_INCREMENT COMMENT 'Primary Key',
`create_time` datetime DEFAULT NULL COMMENT 'Create Time',
`name` varchar(255) DEFAULT NULL,
`company_id` int DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `company_id` (`company_id`),
CONSTRAINT `user_ibfk_1` FOREIGN KEY (`company_id`) REFERENCES `company` (`id`)
) ENGINE = InnoDB AUTO_INCREMENT = 2 DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci
CREATE TABLE
`user_languages` (
`user_id` int NOT NULL,
`language_id` int NOT NULL,
PRIMARY KEY (`user_id`, `language_id`),
KEY `language_id` (`language_id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci
配置表之间的关联关系
user belongsto company
address belongsto company
staff belongsto departmentuser hasone staff
staff many2many role
user many2many languageuser HasMany address
staff HasMany address
company HasMany department
company HasMany staff
staff HasMany language
配置文件中,belongsto/hasone/many2many这三种关联关系的配置如下:(hasmany不需要配置,没有配置的关联关系默认就是hasmany)
"belongstoTables": {
"staff": ["department"],
"user": ["company"],
"address": ["company"]
},
"hasoneTables": {
"user": ["staff"]
},
"many2manyTables": {
"staff_role": ["staff","role"],
"user_languages": ["user","language"]
}
在终端下运行下面的命令:(示例的配置文件gentoolplus_config.json在当前终端目录下即可)
gentoolplus -c .\gentoolplus_config.json
运行结果
dao/model文件夹下:
// Address mapped from table <address>
type Address struct {
ID int64 `gorm:"column:id;primaryKey;autoIncrement:true;comment:Primary Key" json:"id"` // Primary Key
CreateTime *time.Time `gorm:"column:create_time;comment:Create Time" json:"create_time"` // Create Time
Name *string `gorm:"column:name" json:"name"`
UserID *int64 `gorm:"column:user_id" json:"user_id"`
CompanyID *int64 `gorm:"column:company_id" json:"company_id"`
StaffID *int64 `gorm:"column:staff_id" json:"staff_id"`
Company Company `gorm:"foreignKey:ID" json:"company"`
}
// Company mapped from table <company>
type Company struct {
ID int64 `gorm:"column:id;primaryKey;autoIncrement:true;comment:Primary Key" json:"id"` // Primary Key
CreateTime *time.Time `gorm:"column:create_time;comment:Create Time" json:"create_time"` // Create Time
Name *string `gorm:"column:name" json:"name"`
Department []Department `gorm:"foreignKey:CompanyID" json:"department"`
Staff []Staff `gorm:"foreignKey:CompanyID" json:"staff"`
}
// Department mapped from table <department>
type Department struct {
ID int64 `gorm:"column:id;primaryKey;autoIncrement:true;comment:Primary Key" json:"id"` // Primary Key
CreateTime *time.Time `gorm:"column:create_time;comment:Create Time" json:"create_time"` // Create Time
Name *string `gorm:"column:name" json:"name"`
CompanyID *int64 `gorm:"column:company_id" json:"company_id"`
}
// Language mapped from table <language>
type Language struct {
ID int64 `gorm:"column:id;primaryKey;autoIncrement:true;comment:Primary Key" json:"id"` // Primary Key
CreatedAt *time.Time `gorm:"column:created_at;comment:Create Time" json:"created_at"` // Create Time
Name string `gorm:"column:name;not null" json:"name"`
StaffID *int64 `gorm:"column:staff_id" json:"staff_id"`
User []User `gorm:"many2many:user_languages" json:"user"`
}
// Role mapped from table <role>
type Role struct {
ID int64 `gorm:"column:id;primaryKey;autoIncrement:true;comment:Primary Key" json:"id"` // Primary Key
CreateTime *time.Time `gorm:"column:create_time;comment:Create Time" json:"create_time"` // Create Time
Name *string `gorm:"column:name" json:"name"`
Staff []Staff `gorm:"many2many:staff_role" json:"staff"`
}
// Staff mapped from table <staff>
type Staff struct {
ID int64 `gorm:"column:id;primaryKey;autoIncrement:true;comment:Primary Key" json:"id"` // Primary Key
CreateTime *time.Time `gorm:"column:create_time;comment:Create Time" json:"create_time"` // Create Time
Name *string `gorm:"column:name" json:"name"`
CompanyID *int64 `gorm:"column:company_id" json:"company_id"`
UserID *int64 `gorm:"column:user_id" json:"user_id"`
DepartmentID *int64 `gorm:"column:department_id" json:"department_id"`
Address []Address `gorm:"foreignKey:StaffID" json:"address"`
Language []Language `gorm:"foreignKey:StaffID" json:"language"`
Department Department `gorm:"foreignKey:ID" json:"department"`
Role []Role `gorm:"many2many:staff_role" json:"role"`
}
// User mapped from table <user>
type User struct {
ID int64 `gorm:"column:id;primaryKey;autoIncrement:true;comment:Primary Key" json:"id"` // Primary Key
CreateTime *time.Time `gorm:"column:create_time;comment:Create Time" json:"create_time"` // Create Time
Name *string `gorm:"column:name" json:"name"`
CompanyID *int64 `gorm:"column:company_id" json:"company_id"`
Address []Address `gorm:"foreignKey:UserID" json:"address"`
Staff Staff `gorm:"foreignKey:UserID" json:"staff"`
Company Company `gorm:"foreignKey:ID" json:"company"`
Language []Language `gorm:"many2many:user_languages" json:"language"`
}
dao/queryw文件夹下(只截取了部分包含了关联关系的struct,能证明生成了包含关联操作):
type address struct {
addressDo
ALL field.Asterisk
ID field.Int64 // Primary Key
CreateTime field.Time // Create Time
Name field.String
UserID field.Int64
CompanyID field.Int64
StaffID field.Int64
Company addressBelongsToCompany
fieldMap map[string]field.Expr
}
type company struct {
companyDo
ALL field.Asterisk
ID field.Int64 // Primary Key
CreateTime field.Time // Create Time
Name field.String
Department companyHasManyDepartment
Staff companyHasManyStaff
fieldMap map[string]field.Expr
}
type department struct {
departmentDo
ALL field.Asterisk
ID field.Int64 // Primary Key
CreateTime field.Time // Create Time
Name field.String
CompanyID field.Int64
fieldMap map[string]field.Expr
}
type language struct {
languageDo
ALL field.Asterisk
ID field.Int64 // Primary Key
CreatedAt field.Time // Create Time
Name field.String
StaffID field.Int64
User languageManyToManyUser
fieldMap map[string]field.Expr
}
type role struct {
roleDo
ALL field.Asterisk
ID field.Int64 // Primary Key
CreateTime field.Time // Create Time
Name field.String
Staff roleManyToManyStaff
fieldMap map[string]field.Expr
}
type staff struct {
staffDo
ALL field.Asterisk
ID field.Int64 // Primary Key
CreateTime field.Time // Create Time
Name field.String
CompanyID field.Int64
UserID field.Int64
DepartmentID field.Int64
Address staffHasManyAddress
Language staffHasManyLanguage
Department staffBelongsToDepartment
Role staffManyToManyRole
fieldMap map[string]field.Expr
}
type user struct {
userDo
ALL field.Asterisk
ID field.Int64 // Primary Key
CreateTime field.Time // Create Time
Name field.String
CompanyID field.Int64
Address userHasManyAddress
Staff userHasOneStaff
Company userBelongsToCompany
Language userManyToManyLanguage
fieldMap map[string]field.Expr
}
结果分析
- dao/model目录下,生成了所有表的模型文件,数据库CRUD关联操作后的结果都将以这种形式返回数据;
- dao/query目录下,生成了所有表的操作文件,同时生成了所有与关联表的关联关系及其操作代码。
相关源代码已放到GitHub仓库,欢迎来我的github仓库给我加一个start,谢谢!
如果工具使用有任何问题,可以在CSDN文章下留言,一起交流!