support foreign key.添加 外键支持

This commit is contained in:
谢小军
2019-10-27 21:47:10 +08:00
parent d1d1fcb918
commit 56957a92cf
18 changed files with 616 additions and 153 deletions

View File

@@ -38,6 +38,7 @@ Usage:
Flags:
-d, --database string 数据库名
-f, --foreign 是否导出外键关联
-h, --help help for main
-H, --host string 数据库地址.(注意-H为大写)
-o, --outdir string 输出目录
@@ -53,18 +54,18 @@ Flags:
- 数据库表,列字段注释支持
- singular_table 表名复数(大驼峰)
- json tag json标签输出
- gorm.Model 基本模型
- gorm.Model 基本模型 [详信息请看>>>](doc/export_cn.md#151)
- PRIMARY_KEY 将列指定为主键
- UNIQUE 将列指定为唯一
- NOT NULL 将列指定为非 NULL
- INDEX 创建具有或不带名称的索引, 如果多个索引同名则创建复合索引
- UNIQUE_INDEX 和 INDEX 类似,只不过创建的是唯一索引
- 支持外键相关属性 [详信息请看>>>](doc/export_cn.md#114)
### 您可以在这里丰富数据映射类型 [def](https://github.com/xxjwxc/gormt/blob/master/data/view/gtools/def.go) 。
### 您可以在这里丰富数据映射类型 [def](data/view/cnf/def.go) 。
## 5. 示例展示
- sql:
sql:
```
CREATE TABLE `user_account_tbl` (
`id` int(11) NOT NULL AUTO_INCREMENT,
@@ -72,122 +73,39 @@ CREATE TABLE `user_account_tbl` (
`password` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`account_type` int(11) NOT NULL DEFAULT '0' COMMENT '帐号类型:0手机号1邮件',
`app_key` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT 'authbucket_oauth2_client表的id',
`user_info_id` int(11) NOT NULL,
`user_info_tbl_id` int(11) NOT NULL,
`reg_time` datetime DEFAULT NULL,
`reg_ip` varchar(15) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`bundle_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`describ` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `account` (`account`),
UNIQUE KEY `UNIQ_5696AD037D3656A4` (`app_key`,`user_info_id`) USING BTREE,
KEY `user_info_id` (`user_info_id`),
CONSTRAINT `1` FOREIGN KEY (`user_info_id`) REFERENCES `user_info_tbl` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='用户信息'
UNIQUE KEY `account` (`account`) USING BTREE,
KEY `user_info_id` (`user_info_tbl_id`) USING BTREE,
CONSTRAINT `user_account_tbl_ibfk_1` FOREIGN KEY (`user_info_tbl_id`) REFERENCES `user_info_tbl` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE=InnoDB AUTO_INCREMENT=38 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='用户账号'
```
- 参数:singular_table = false simple = false
###### --->导出结果
```
// 用户信息
// UserAccountTbl 用户账号
type UserAccountTbl struct {
ID int `gorm:"primary_key;column:id;type:int(11);not null" json:"-"` //
Account string `gorm:"unique;column:account;type:varchar(64);not null" json:"account"` //
Password string `gorm:"column:password;type:varchar(64);not null" json:"password"` //
AccountType int `gorm:"column:account_type;type:int(11);not null" json:"account_type"` // 帐号类型:0手机号1邮件
AppKey string `json:"app_key" gorm:"unique_index:UNIQ_5696AD037D3656A4;column:app_key;type:varchar(255);not null"` // authbucket_oauth2_client表的id
UserInfoID int `gorm:"unique_index:UNIQ_5696AD037D3656A4;index;column:user_info_id;type:int(11);not null" json:"user_info_id"` //
RegTime time.Time `gorm:"column:reg_time;type:datetime" json:"reg_time"` //
RegIP string `gorm:"column:reg_ip;type:varchar(15)" json:"reg_ip"` //
BundleID string `json:"bundle_id" gorm:"column:bundle_id;type:varchar(255)"` //
Describ string `gorm:"column:describ;type:varchar(255)" json:"describ"` //
ID int `gorm:"primary_key"`
Account string `gorm:"unique"`
Password string
AccountType int // 帐号类型:0手机号1邮件
AppKey string // authbucket_oauth2_client表的id
UserInfoTblID int `gorm:"index"`
UserInfoTbl UserInfoTbl `gorm:"association_foreignkey:user_info_tbl_id;foreignkey:id"` // 用户信息
RegTime time.Time
RegIP string
BundleID string
Describ string
}
```
- 参数:singular_table = true simple = false
[更多>>>](doc/export_cn.md)
###### --->导出结果
```
type User_account_tbl struct {
Id int `gorm:"primary_key;column:id;type:int(11);not null" json:"-"` //
Account string `gorm:"unique;column:account;type:varchar(64);not null" json:"account"` //
Password string `gorm:"column:password;type:varchar(64);not null" json:"password"` //
Account_type int `gorm:"column:account_type;type:int(11);not null" json:"account_type"` // 帐号类型:0手机号1邮件
App_key string `gorm:"unique_index:UNIQ_5696AD037D3656A4;column:app_key;type:varchar(255);not null" json:"app_key"` // authbucket_oauth2_client表的id
User_info_id int `gorm:"unique_index:UNIQ_5696AD037D3656A4;index;column:user_info_id;type:int(11);not null" json:"user_info_id"` //
Reg_time time.Time `gorm:"column:reg_time;type:datetime" json:"reg_time"` //
Reg_ip string `gorm:"column:reg_ip;type:varchar(15)" json:"reg_ip"` //
Bundle_id string `gorm:"column:bundle_id;type:varchar(255)" json:"bundle_id"` //
Describ string `gorm:"column:describ;type:varchar(255)" json:"describ"` //
}
```
- 参数:singular_table = false simple = true isJsonTag = true
###### --->导出结果
```
// 用户信息
type UserAccountTbl struct {
ID int `json:"-" gorm:"primary_key"` //
Account string `gorm:"unique" json:"account"` //
Password string `json:"password"` //
AccountType int `json:"account_type"` // 帐号类型:0手机号1邮件
AppKey string `gorm:"unique_index:UNIQ_5696AD037D3656A4" json:"app_key"` // authbucket_oauth2_client表的id
UserInfoID int `json:"user_info_id" gorm:"unique_index:UNIQ_5696AD037D3656A4;index"` //
RegTime time.Time `json:"reg_time"` //
RegIP string `json:"reg_ip"` //
BundleID string `json:"bundle_id"` //
Describ string `json:"describ"` //
}
```
- 参数:singular_table = false simple = true isJsonTag = false
###### --->导出结果
```
// 用户信息
type UserAccountTbl struct {
ID int `gorm:"primary_key"` //
Account string `gorm:"unique"` //
Password string //
AccountType int // 帐号类型:0手机号1邮件
AppKey string `gorm:"unique_index:UNIQ_5696AD037D3656A4"` // authbucket_oauth2_client表的id
UserInfoID int `gorm:"unique_index:UNIQ_5696AD037D3656A4;index"` //
RegTime time.Time //
RegIP string //
BundleID string //
Describ string //
}
```
- sql:
```
CREATE TABLE `user_info_tbl` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`nickname` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`headurl` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`deleted_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='用户信息'
```
- 参数:singular_table = false simple = true isJsonTag = false
###### --->导出结果
```
// 用户信息
type UserInfoTbl struct {
gorm.Model //
Nickname string //
Headurl string //
}
```
## 6. 构建
```
make windows
@@ -200,7 +118,11 @@ or
go generate
```
## 7. 提供一个windows 可视化工具
## 7. 下一步计划
- 加入相关快捷函数(OrmFunc)
## 8. 提供一个windows 可视化工具
![图片描述](/image/gormt/1.png)
@@ -212,8 +134,5 @@ go generate
[下载地址](https://github.com/xxjwxc/gormt/releases/download/v1.1.0/v1.0.zip)
## 7. 下一步计划
- 加入外键支持(ForeignKey)
- ###### [传送门](https://xxjwxc.github.io/post/gormtools/)

View File

@@ -1,16 +0,0 @@
serial_number = "1.0" #版本号
service_name = "" #服务名
service_displayname = "" #服务显示名
sercice_desc = "" #服务描述
is_dev = false # 是否开发者模式
out_dir = "./db" # 输出目录
singular_table = false # 单表模式:true:禁用表名复数,false:采用表明复数 参考:gorm.SingularTable
simple = true #简单输出
isJsonTag = true #是否打json标记
[mysql_info]
host = "127.0.0.1"
port = 3306
username = "root"
password = "qwer"
database = "oauth_db"

17
config.yml Normal file
View File

@@ -0,0 +1,17 @@
base :
serial_number : "1.0" #版本号
service_name : #服务名
service_displayname : #服务显示名
sercice_desc : #服务描述
is_dev : false # 是否开发者模式
out_dir : ./model # 输出目录
singular_table : false # 单表模式:true:禁用表名复数,false:采用表明复数 参考:gorm.SingularTable
simple : true #简单输出
is_json_tag : false #是否打json标记
is_foreign_key : true #是否导出外键关联
mysql_info:
host : 127.0.0.1
port : 3306
username : root
password : qwer
database : oauth_db

View File

@@ -17,6 +17,7 @@ import (
var mysqlInfo config.MysqlDbInfo
var outDir string
var singularTable bool
var foreignKey bool
var rootCmd = &cobra.Command{
Use: "main",
@@ -56,6 +57,9 @@ func init() {
rootCmd.PersistentFlags().BoolVarP(&singularTable, "singular", "s", false, "是否禁用表名复数")
rootCmd.MarkFlagRequired("singular")
rootCmd.PersistentFlags().BoolVarP(&foreignKey, "foreign", "f", false, "是否导出外键关联")
rootCmd.MarkFlagRequired("foreign")
rootCmd.Flags().IntVar(&mysqlInfo.Port, "port", 3306, "端口号")
}
@@ -102,4 +106,8 @@ func MergeMysqlDbInfo() {
if singularTable {
config.SetSingularTable(singularTable)
}
if foreignKey {
config.SetForeignKey(foreignKey)
}
}

View File

@@ -4,12 +4,13 @@ import "fmt"
// Config custom config struct
type Config struct {
CfgBase
MySQLInfo MysqlDbInfo `toml:"mysql_info"`
OutDir string `toml:"out_dir"`
Simple bool `toml:"simple"`
IsJSONTag bool `toml:"isJsonTag"`
SingularTable bool `toml:"singular_table"`
CfgBase `yaml:"base"`
MySQLInfo MysqlDbInfo `yaml:"mysql_info"`
OutDir string `yaml:"out_dir"`
Simple bool `yaml:"simple"`
IsJSONTag bool `yaml:"is_json_tag"`
SingularTable bool `yaml:"singular_table"`
IsForeignKey bool `yaml:"is_foreign_key"`
}
// MysqlDbInfo mysql database information. mysql 数据库信息
@@ -71,3 +72,13 @@ func GetSimple() bool {
func GetIsJSONTag() bool {
return _map.IsJSONTag
}
// GetIsForeignKey if is foreign key
func GetIsForeignKey() bool {
return _map.IsForeignKey
}
// SetForeignKey Set if is foreign key.设置是否外键关联
func SetForeignKey(b bool) {
_map.IsForeignKey = b
}

View File

@@ -2,20 +2,20 @@ package config
import (
"fmt"
"io/ioutil"
"github.com/xxjwxc/public/dev"
"github.com/xxjwxc/public/tools"
"github.com/BurntSushi/toml"
"gopkg.in/yaml.v2"
)
// CfgBase base config struct
type CfgBase struct {
SerialNumber string `json:"serial_number" toml:"serial_number"` // version.版本号
ServiceName string `json:"service_name" toml:"service_name"` // service name .service名字
ServiceDisplayname string `json:"service_displayname" toml:"service_displayname"` // display name .显示名
SerciceDesc string `json:"sercice_desc" toml:"sercice_desc"` // sercice desc .service描述
IsDev bool `json:"is_dev" toml:"is_dev"` // Is it a development version?是否是开发版本
SerialNumber string `json:"serial_number" yaml:"serial_number"` // version.版本号
ServiceName string `json:"service_name" yaml:"service_name"` // service name .service名字
ServiceDisplayname string `json:"service_displayname" yaml:"service_displayname"` // display name .显示名
SerciceDesc string `json:"sercice_desc" yaml:"sercice_desc"` // sercice desc .service描述
IsDev bool `json:"is_dev" yaml:"is_dev"` // Is it a development version?是否是开发版本
}
var _map = Config{}
@@ -27,7 +27,7 @@ func init() {
func onInit() {
path := tools.GetModelPath()
err := InitFile(path + "/config.toml")
err := InitFile(path + "/config.yml")
if err != nil {
fmt.Println("InitFile: ", err.Error())
return
@@ -36,7 +36,11 @@ func onInit() {
// InitFile default value from file .
func InitFile(filename string) error {
if _, err := toml.DecodeFile(filename, &_map); err != nil {
bs, err := ioutil.ReadFile(filename)
if err != nil {
return err
}
if err := yaml.Unmarshal(bs, &_map); err != nil {
fmt.Println("read toml error: ", err.Error())
return err
}

View File

@@ -7,6 +7,23 @@ import (
const (
testFile = `
serial_number : "1.0" #版本号
service_name : #服务名
service_displayname : #服务显示名
sercice_desc : #服务描述
is_dev : false # 是否开发者模式
out_dir : ./db # 输出目录
singular_table : false # 单表模式:true:禁用表名复数,false:采用表明复数 参考:gorm.SingularTable
simple : true #简单输出
isJsonTag : true #是否打json标记
mysql_info:
host : 127.0.0.1
port : 3306
username : root
password : qwer
database : oauth_db
`
)

View File

@@ -37,13 +37,16 @@ type TabInfo struct {
// ColumusInfo Columus list .表列信息
type ColumusInfo struct {
BaseInfo
Type string // Type.类型标记
//Index string // index or unique_index or ''
Index []KList // index list.index列表
IsNull bool // null if db is set null
Type string // Type.类型标记
Index []KList // index list.index列表
IsNull bool // null if db is set null
ForeignKeyList []ForeignKey // Foreign key list . 表的外键信息
}
//
// Tags map[string][]string // tages.标记
// ForeignKey Foreign key of db info . 表的外键信息
type ForeignKey struct {
TableName string // Affected tables . 该索引受影响的表
ColumnName string // Which column of the affected table.该索引受影响的表的哪一列
}
// KList database index /unique_index list.数据库index /unique_index 列表

View File

@@ -1,6 +1,10 @@
package genmysql
import "strings"
import (
"strings"
"github.com/xxjwxc/gormt/data/view/model"
)
// filterModel filter.过滤 gorm.Model
func filterModel(list *[]genColumns) bool {
@@ -25,3 +29,15 @@ func filterModel(list *[]genColumns) bool {
return false
}
// fixForeignKey fix foreign key.过滤外键
func fixForeignKey(list []genForeignKey, columuName string, result *[]model.ForeignKey) {
for _, v := range list {
if strings.EqualFold(v.ColumnName, columuName) { // find it .找到了
*result = append(*result, model.ForeignKey{
TableName: v.ReferencedTableName,
ColumnName: v.ReferencedColumnName,
})
}
}
}

View File

@@ -14,3 +14,15 @@ type genColumns struct {
Desc string `gorm:"column:Comment"`
Null string `gorm:"column:Null"`
}
//select table_schema,table_name,column_name,referenced_table_schema,referenced_table_name,referenced_column_name from INFORMATION_SCHEMA.KEY_COLUMN_USAGE
// where table_schema ='matrix' AND REFERENCED_TABLE_NAME IS NOT NULL AND TABLE_NAME = 'credit_card' ;
// genForeignKey Foreign key of db info . 表的外键信息
type genForeignKey struct {
TableSchema string `gorm:"column:table_schema"` // Database of columns.列所在的数据库
TableName string `gorm:"column:table_name"` // Data table of column.列所在的数据表
ColumnName string `gorm:"column:column_name"` // Column names.列名
ReferencedTableSchema string `gorm:"column:referenced_table_schema"` // The database where the index is located.该索引所在的数据库
ReferencedTableName string `gorm:"column:referenced_table_name"` // Affected tables . 该索引受影响的表
ReferencedColumnName string `gorm:"column:referenced_column_name"` // Which column of the affected table.该索引受影响的表的哪一列
}

View File

@@ -105,6 +105,12 @@ func getTableElement(orm *mysqldb.MySqlDB, tab string) (el []model.ColumusInfo)
}
// -----------------end
// ForeignKey
var foreignKeyList []genForeignKey
orm.Raw(`select table_schema,table_name,column_name,referenced_table_schema,referenced_table_name,referenced_column_name from INFORMATION_SCHEMA.KEY_COLUMN_USAGE
where table_schema = ? AND REFERENCED_TABLE_NAME IS NOT NULL AND TABLE_NAME = ? `, config.GetMysqlDbInfo().Database, tab).Find(&foreignKeyList)
// ------------------end
for _, v := range list {
var tmp model.ColumusInfo
tmp.Name = v.Field
@@ -138,6 +144,10 @@ func getTableElement(orm *mysqldb.MySqlDB, tab string) (el []model.ColumusInfo)
}
tmp.IsNull = strings.EqualFold(v.Null, "YES")
// ForeignKey
fixForeignKey(foreignKeyList, tmp.Name, &tmp.ForeignKeyList)
// -----------------end
el = append(el, tmp)
}
return

View File

@@ -7,15 +7,26 @@ import (
"github.com/xxjwxc/gormt/data/view/genstruct"
)
type _Model struct {
info DBInfo
}
// Generate build code string.生成代码
func Generate(info DBInfo) string {
m := _Model{
info: info,
}
return m.generate()
}
func (m *_Model) generate() string {
var pkg genstruct.GenPackage
pkg.SetPackage(info.PackageName) //package name
for _, tab := range info.TabList {
pkg.SetPackage(m.info.PackageName) //package name
for _, tab := range m.info.TabList {
var sct genstruct.GenStruct
sct.SetStructName(getCamelName(tab.Name)) // Big hump.大驼峰
sct.SetNotes(tab.Notes)
sct.AddElement(getTableElement(tab.Em)...) // build element.构造元素
sct.AddElement(m.genTableElement(tab.Em)...) // build element.构造元素
sct.SetCreatTableStr(tab.SQLBuildStr)
pkg.AddStruct(sct)
}
@@ -23,9 +34,9 @@ func Generate(info DBInfo) string {
return pkg.Generate()
}
// getTableElement Get table columns and comments.获取表列及注释
func getTableElement(tabs []ColumusInfo) (el []genstruct.GenElement) {
for _, v := range tabs {
// genTableElement Get table columns and comments.获取表列及注释
func (m *_Model) genTableElement(cols []ColumusInfo) (el []genstruct.GenElement) {
for _, v := range cols {
var tmp genstruct.GenElement
if strings.EqualFold(v.Type, "gorm.Model") { // gorm model
tmp.SetType(v.Type) //
@@ -74,7 +85,91 @@ func getTableElement(tabs []ColumusInfo) (el []genstruct.GenElement) {
}
}
el = append(el, tmp)
// ForeignKey
if config.GetIsForeignKey() && len(v.ForeignKeyList) > 0 {
fklist := m.genForeignKey(v)
if len(fklist) > 0 {
el = append(el, fklist...)
}
}
// -----------end
}
return
}
// genForeignKey Get information about foreign key of table column.获取表列外键相关信息
func (m *_Model) genForeignKey(col ColumusInfo) (fklist []genstruct.GenElement) {
for _, v := range col.ForeignKeyList {
isMulti, isFind, notes := m.getColumusKeyMulti(v.TableName, v.ColumnName)
if isFind {
var tmp genstruct.GenElement
tmp.SetNotes(notes)
if isMulti {
tmp.SetName(getCamelName(v.TableName) + "List")
tmp.SetType("[]" + getCamelName(v.TableName))
} else {
tmp.SetName(getCamelName(v.TableName))
tmp.SetType(getCamelName(v.TableName))
}
tmp.AddTag(_tagGorm, "association_foreignkey:"+col.Name)
tmp.AddTag(_tagGorm, "foreignkey:"+v.ColumnName)
// json tag
if config.GetIsJSONTag() {
tmp.AddTag(_tagJSON, v.TableName+"_list")
}
fklist = append(fklist, tmp)
}
}
return
}
func (m *_Model) getColumusKeyMulti(tableName, col string) (isMulti bool, isFind bool, notes string) {
var haveGomod bool
for _, v := range m.info.TabList {
if strings.EqualFold(v.Name, tableName) {
for _, v1 := range v.Em {
if strings.EqualFold(v1.Name, col) {
for _, v2 := range v1.Index {
switch v2.Key {
case ColumusKeyPrimary, ColumusKeyUnique, ColumusKeyUniqueIndex: // primary key unique key . 主键,唯一索引
{
return false, true, v.Notes
}
// case ColumusKeyIndex: // index key. 复合索引
// {
// isMulti = true
// }
}
}
return true, true, v.Notes
} else if strings.EqualFold(v1.Type, "gorm.Model") {
haveGomod = true
notes = v.Notes
}
}
break
}
}
// default gorm.Model
if haveGomod {
if strings.EqualFold(col, "id") {
return false, true, notes
}
if strings.EqualFold(col, "created_at") ||
strings.EqualFold(col, "updated_at") ||
strings.EqualFold(col, "deleted_at") {
return true, true, notes
}
}
return false, false, ""
// -----------------end
}

126
doc/export.md Normal file
View File

@@ -0,0 +1,126 @@
## 5. 导出
- sql:
```
CREATE TABLE `user_account_tbl` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`account` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`password` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`account_type` int(11) NOT NULL DEFAULT '0' COMMENT '帐号类型:0手机号1邮件',
`app_key` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT 'authbucket_oauth2_client表的id',
`user_info_id` int(11) NOT NULL,
`reg_time` datetime DEFAULT NULL,
`reg_ip` varchar(15) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`bundle_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`describ` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `account` (`account`),
UNIQUE KEY `UNIQ_5696AD037D3656A4` (`app_key`,`user_info_id`) USING BTREE,
KEY `user_info_id` (`user_info_id`),
CONSTRAINT `1` FOREIGN KEY (`user_info_id`) REFERENCES `user_info_tbl` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='用户信息'
```
- 参数:singular_table = false simple = false
###### --->导出结果
```
// 用户信息
type UserAccountTbl struct {
ID int `gorm:"primary_key;column:id;type:int(11);not null" json:"-"` //
Account string `gorm:"unique;column:account;type:varchar(64);not null" json:"account"` //
Password string `gorm:"column:password;type:varchar(64);not null" json:"password"` //
AccountType int `gorm:"column:account_type;type:int(11);not null" json:"account_type"` // 帐号类型:0手机号1邮件
AppKey string `json:"app_key" gorm:"unique_index:UNIQ_5696AD037D3656A4;column:app_key;type:varchar(255);not null"` // authbucket_oauth2_client表的id
UserInfoID int `gorm:"unique_index:UNIQ_5696AD037D3656A4;index;column:user_info_id;type:int(11);not null" json:"user_info_id"` //
RegTime time.Time `gorm:"column:reg_time;type:datetime" json:"reg_time"` //
RegIP string `gorm:"column:reg_ip;type:varchar(15)" json:"reg_ip"` //
BundleID string `json:"bundle_id" gorm:"column:bundle_id;type:varchar(255)"` //
Describ string `gorm:"column:describ;type:varchar(255)" json:"describ"` //
}
```
- 参数:singular_table = true simple = false
###### --->导出结果
```
type User_account_tbl struct {
Id int `gorm:"primary_key;column:id;type:int(11);not null" json:"-"` //
Account string `gorm:"unique;column:account;type:varchar(64);not null" json:"account"` //
Password string `gorm:"column:password;type:varchar(64);not null" json:"password"` //
Account_type int `gorm:"column:account_type;type:int(11);not null" json:"account_type"` // 帐号类型:0手机号1邮件
App_key string `gorm:"unique_index:UNIQ_5696AD037D3656A4;column:app_key;type:varchar(255);not null" json:"app_key"` // authbucket_oauth2_client表的id
User_info_id int `gorm:"unique_index:UNIQ_5696AD037D3656A4;index;column:user_info_id;type:int(11);not null" json:"user_info_id"` //
Reg_time time.Time `gorm:"column:reg_time;type:datetime" json:"reg_time"` //
Reg_ip string `gorm:"column:reg_ip;type:varchar(15)" json:"reg_ip"` //
Bundle_id string `gorm:"column:bundle_id;type:varchar(255)" json:"bundle_id"` //
Describ string `gorm:"column:describ;type:varchar(255)" json:"describ"` //
}
```
- 参数:singular_table = false simple = true isJsonTag = true
###### --->导出结果
```
// 用户信息
type UserAccountTbl struct {
ID int `json:"-" gorm:"primary_key"` //
Account string `gorm:"unique" json:"account"` //
Password string `json:"password"` //
AccountType int `json:"account_type"` // 帐号类型:0手机号1邮件
AppKey string `gorm:"unique_index:UNIQ_5696AD037D3656A4" json:"app_key"` // authbucket_oauth2_client表的id
UserInfoID int `json:"user_info_id" gorm:"unique_index:UNIQ_5696AD037D3656A4;index"` //
RegTime time.Time `json:"reg_time"` //
RegIP string `json:"reg_ip"` //
BundleID string `json:"bundle_id"` //
Describ string `json:"describ"` //
}
```
- 参数:singular_table = false simple = true isJsonTag = false
###### --->导出结果
```
// 用户信息
type UserAccountTbl struct {
ID int `gorm:"primary_key"` //
Account string `gorm:"unique"` //
Password string //
AccountType int // 帐号类型:0手机号1邮件
AppKey string `gorm:"unique_index:UNIQ_5696AD037D3656A4"` // authbucket_oauth2_client表的id
UserInfoID int `gorm:"unique_index:UNIQ_5696AD037D3656A4;index"` //
RegTime time.Time //
RegIP string //
BundleID string //
Describ string //
}
```
- sql:
```
CREATE TABLE `user_info_tbl` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`nickname` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`headurl` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`deleted_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='用户信息'
```
- 参数:singular_table = false simple = true isJsonTag = false
###### --->导出结果
```
// 用户信息
type UserInfoTbl struct {
gorm.Model //
Nickname string //
Headurl string //
}
```

163
doc/export_cn.md Normal file
View File

@@ -0,0 +1,163 @@
## 5. 导出
- sql:
```
CREATE TABLE `user_account_tbl` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`account` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`password` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`account_type` int(11) NOT NULL DEFAULT '0' COMMENT '帐号类型:0手机号1邮件',
`app_key` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT 'authbucket_oauth2_client表的id',
`user_info_tbl_id` int(11) NOT NULL,
`reg_time` datetime DEFAULT NULL,
`reg_ip` varchar(15) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`bundle_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`describ` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `account` (`account`) USING BTREE,
UNIQUE KEY `UNIQ_5696AD037D3656A4` (`app_key`,`user_info_tbl_id`) USING BTREE,
KEY `user_info_id` (`user_info_tbl_id`) USING BTREE,
CONSTRAINT `user_account_tbl_ibfk_1` FOREIGN KEY (`user_info_tbl_id`) REFERENCES `user_info_tbl` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='用户账号'
```
-------------
- 参数:singular_table = false simple = false is_foreign_key = false
###### --->导出结果
```
// UserAccountTbl 用户账号
type UserAccountTbl struct {
ID int `gorm:"primary_key;column:id;type:int(11);not null" json:"-"`
Account string `gorm:"unique;column:account;type:varchar(64);not null" json:"account"`
Password string `gorm:"column:password;type:varchar(64);not null" json:"password"`
AccountType int `gorm:"column:account_type;type:int(11);not null" json:"account_type"` // 帐号类型:0手机号1邮件
AppKey string `gorm:"unique_index:UNIQ_5696AD037D3656A4;column:app_key;type:varchar(255);not null" json:"app_key"` // authbucket_oauth2_client表的id
UserInfoTblID int `gorm:"unique_index:UNIQ_5696AD037D3656A4;index;column:user_info_tbl_id;type:int(11);not null" json:"user_info_tbl_id"`
RegTime time.Time `gorm:"column:reg_time;type:datetime" json:"reg_time"`
RegIP string `gorm:"column:reg_ip;type:varchar(15)" json:"reg_ip"`
BundleID string `gorm:"column:bundle_id;type:varchar(255)" json:"bundle_id"`
Describ string `gorm:"column:describ;type:varchar(255)" json:"describ"`
}
```
-------------
- 参数:singular_table = true simple = false is_foreign_key = false
###### --->导出结果
```
// UserAccountTbl 用户账号
type User_account_tbl struct {
Id int `gorm:"primary_key;column:id;type:int(11);not null" json:"-"`
Account string `gorm:"unique;column:account;type:varchar(64);not null" json:"account"`
Password string `gorm:"column:password;type:varchar(64);not null" json:"password"`
Account_type int `gorm:"column:account_type;type:int(11);not null" json:"account_type"` // 帐号类型:0手机号1邮件
App_key string `gorm:"unique_index:UNIQ_5696AD037D3656A4;column:app_key;type:varchar(255);not null" json:"app_key"` // authbucket_oauth2_client表的id
User_info_tbl_id int `gorm:"unique_index:UNIQ_5696AD037D3656A4;index;column:user_info_tbl_id;type:int(11);not null" json:"user_info_tbl_id"`
Reg_time time.Time `gorm:"column:reg_time;type:datetime" json:"reg_time"`
Reg_ip string `gorm:"column:reg_ip;type:varchar(15)" json:"reg_ip"`
Bundle_id string `gorm:"column:bundle_id;type:varchar(255)" json:"bundle_id"`
Describ string `gorm:"column:describ;type:varchar(255)" json:"describ"`
}
```
-------------
- 参数:singular_table = false simple = true is_json_tag = true is_foreign_key = false
###### --->导出结果
```
// UserAccountTbl 用户账号
type UserAccountTbl struct {
ID int `gorm:"primary_key" json:"-"`
Account string `gorm:"unique" json:"account"`
Password string `json:"password"`
AccountType int `json:"account_type"` // 帐号类型:0手机号1邮件
AppKey string `gorm:"unique_index:UNIQ_5696AD037D3656A4" json:"app_key"` // authbucket_oauth2_client表的id
UserInfoTblID int `gorm:"unique_index:UNIQ_5696AD037D3656A4;index" json:"user_info_tbl_id"`
RegTime time.Time `json:"reg_time"`
RegIP string `json:"reg_ip"`
BundleID string `json:"bundle_id"`
Describ string `json:"describ"`
}
```
--------------
- 参数:singular_table = false simple = true is_json_tag = false is_foreign_key = false
###### --->导出结果
```
// UserAccountTbl 用户账号
type UserAccountTbl struct {
ID int `gorm:"primary_key"`
Account string `gorm:"unique"`
Password string
AccountType int // 帐号类型:0手机号1邮件
AppKey string `gorm:"unique_index:UNIQ_5696AD037D3656A4"` // authbucket_oauth2_client表的id
UserInfoTblID int `gorm:"unique_index:UNIQ_5696AD037D3656A4;index"`
RegTime time.Time
RegIP string
BundleID string
Describ string
}
```
--------------
- 参数:singular_table = false simple = true is_json_tag = false is_foreign_key = true
###### --->导出结果
```
// UserAccountTbl 用户账号
type UserAccountTbl struct {
ID int `gorm:"primary_key"`
Account string `gorm:"unique"`
Password string
AccountType int // 帐号类型:0手机号1邮件
AppKey string `gorm:"unique_index:UNIQ_5696AD037D3656A4"` // authbucket_oauth2_client表的id
UserInfoTblID int `gorm:"unique_index:UNIQ_5696AD037D3656A4;index"`
UserInfoTbl UserInfoTbl `gorm:"association_foreignkey:user_info_tbl_id;foreignkey:id"` // 用户信息
RegTime time.Time
RegIP string
BundleID string
Describ string
}
```
--------------
- sql:
```
CREATE TABLE `user_info_tbl` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`nickname` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`headurl` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`deleted_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
KEY `id` (`id`,`created_at`)
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='用户信息'
```
- 参数:singular_table = false simple = true is_json_tag = false
###### --->导出结果
```
// UserInfoTbl 用户信息
type UserInfoTbl struct {
gorm.Model
Nickname string
Headurl string
}
```

2
go.mod
View File

@@ -12,4 +12,6 @@ require (
github.com/xxjwxc/public v0.0.0-20190915135914-aefa9155c004
gopkg.in/go-playground/assert.v1 v1.2.1 // indirect
gopkg.in/go-playground/validator.v9 v9.29.1
gopkg.in/yaml.v2 v2.2.2
gopkg.in/yaml.v3 v3.0.0-20191026110619-0b21df46bc1d
)

9
go.sum
View File

@@ -1,5 +1,6 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.37.4 h1:glPeL3BQJsbF6aIIYfZizMwc5LTYz250bDMjttbBGAU=
cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
@@ -22,10 +23,12 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3 h1:tkum0XDgfR0jcVVXuTsYv/erY2NnEDqwRojbxR1rBYA=
github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y=
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
@@ -65,6 +68,7 @@ github.com/jinzhu/gorm v1.9.10 h1:HvrsqdhCW78xpJF67g1hMxS6eCToo9PZH4LDB8WKPac=
github.com/jinzhu/gorm v1.9.10/go.mod h1:Kh6hTsSGffh4ui079FHrR5Gg+5D0hgihqDcsDN2BBJY=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.0.1 h1:HjfetcXq097iXP0uoPCdnM4Efp5/9MsM0/M+XOTeR3M=
github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
@@ -74,8 +78,10 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/leodido/go-urn v1.1.0 h1:Sm1gr51B1kKyfD2BlRcLSiEkffoG96g6TPv6eRoEiB8=
github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw=
github.com/lib/pq v1.1.1 h1:sJZmqHoEaY7f+NPP8pgLB/WxulyR3fewgCM2qaSlBb4=
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o=
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
@@ -131,6 +137,7 @@ go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c h1:Vj5n4GlwjmQteupaxJ9+0FNOmBrHfq7vN4btdGoDZgI=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -191,6 +198,8 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20191026110619-0b21df46bc1d h1:LCPbGQ34PMrwad11aMZ+dbz5SAsq/0ySjRwQ8I9Qwd8=
gopkg.in/yaml.v3 v3.0.0-20191026110619-0b21df46bc1d/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

50
sample/sample_test.go Normal file
View File

@@ -0,0 +1,50 @@
package main
import (
"fmt"
"testing"
"time"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
"github.com/xxjwxc/gormt/model"
"github.com/xxjwxc/public/mysqldb"
)
const (
sqlConn = "root:qwer@tcp(localhost:3306)/oauth_db?charset=utf8&parseTime=true&loc=Local&timeout=10s"
)
func TestForeignKey(t *testing.T) {
db, err := gorm.Open("mysql", sqlConn)
if err != nil {
panic(err)
}
defer db.Close()
db.SingularTable(true) // 全局禁用表名复数
db.LogMode(true)
var p0 model.UserAccountTbl
p0.Account = "test"
p0.RegTime = time.Now()
p0.UserInfoTbl.Nickname = "testBBB"
p0.UserInfoTblID = 1
db.Save(&p0.UserInfoTbl)
p0.UserInfoTblID = (int)(p0.UserInfoTbl.ID)
db.Save(&p0)
var p1 model.UserAccountTbl
db.Where("account = ?", "test").Find(&p1)
db.Model(&p1).Related(&p1.UserInfoTbl) // 外键关联
fmt.Println(p1)
}
func TestForeignKeyOrm(t *testing.T) {
orm := mysqldb.OnInitDBOrm(sqlConn)
defer orm.OnDestoryDB()
var p model.UserAccountTbl
orm.Find(&p)
orm.Model(&p).Related(&p.UserInfoTbl) // 外键关联
fmt.Println(p)
}

17
test.yam Normal file
View File

@@ -0,0 +1,17 @@
cfgbase:
serial_number: aaa
service_name: bbb
service_displayname: ""
sercice_desc: ""
is_dev: false
mysqlinfo:
host: ""
port: 0
username: ""
password: ""
database: ""
outdir: ""
simple: true
isjsontag: false
singulartable: false