├── bin └── automatic ├── .idea ├── misc.xml ├── vcs.xml ├── modules.xml ├── go-struct-auto.iml └── workspace.xml ├── models └── mall_account.go ├── README.md └── automatic.go /bin/automatic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whr-helen/go-struct-auto/HEAD/bin/automatic -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/go-struct-auto.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /models/mall_account.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | type Mall_account struct { 4 | Id int `xorm:"not null pk autoincr comment('序号') INT(11)" json:"id"` 5 | Name string `xorm:"comment('名称')" json:"name"` 6 | Openid string `xorm:"comment('唯一标识')" json:"openid"` 7 | Mobile string `xorm:"comment('手机号')" json:"mobile"` 8 | Headimgurl string `xorm:"comment('头像')" json:"headimgurl"` 9 | Price float64 `xorm:"comment('价格')" json:"price"` 10 | Createtime int `xorm:"comment('创建时间')" json:"createtime"` 11 | Code string `xorm:"comment('支付密码')" json:"code"` 12 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 自动构建工具使用 2 | 3 | 安装包命令: go get github.com/whr-helen/go-struct-auto 4 | 5 | 6 | 7 | 注释:参数信息 8 | 9 | -host host 改为自己数据库的地址 ( 默认 127.0.0.1) 10 | 11 | -port port 改为自己数据库的端口 ( 默认 3306) 12 | 13 | -acc acc 改为自己数据库的账号 ( 默认 root) 14 | 15 | -pwd pwd 改为自己数据库的密码 ( 默认 123123) 16 | 17 | -d dbname 改为自己数据库的名称 (必填) 18 | 19 | -path ./models 改为存放路径 (可选默认为./models ) 20 | 21 | -t account,user 改为要生成的表名称、可多个 (可选默认全部生成) 22 | 23 | 24 | 25 | 一、生成数据库所有表 结构体: 26 | 27 | ① 推荐使用方法(支持 linux or mac) 28 | 29 | 生成命令: ./bin/automatic -d dbname -path ./models 30 | 31 | 32 | ② 修改生成工具代码(支持 linux or mac or windows)如果生成出来的结构不是我们所需要的可以修改 automatic.go 文件 33 | 34 | 命令: go run automatic.go -d dbname -path ./models 35 | 36 | 二、生成单个多个表 结构体: 37 | 38 | 命令(支持 linux or mac): ./bin/automatic -d dbname -t account,user 39 | 40 | 41 | 命令(支持 linux or mac or windows): go run automatic.go -d dbname -acc root -pwd 123123 -t account -------------------------------------------------------------------------------- /automatic.go: -------------------------------------------------------------------------------- 1 | package main 2 | //whr-helen 2019 3 | 4 | import ( 5 | _ "github.com/go-sql-driver/mysql" 6 | "database/sql" 7 | "fmt" 8 | _"strings" 9 | "io/ioutil" 10 | "flag" 11 | "os" 12 | "strings" 13 | ) 14 | //用户输入配置 15 | var( 16 | db_host string //数据库地址 17 | db_port string //数据库端口 18 | db_name string //数据库名称 19 | db_account string //数据库账号 20 | db_pwd string //数据库密码 21 | path string //结构体保存路径 22 | tables string //表名称 23 | ) 24 | //表类型 25 | type Dbtabels struct{ 26 | Name string `json:"name"` 27 | } 28 | //数据字段类型 29 | type Column struct { 30 | Columname string `json:"columname"` 31 | Datatype string `json:"datatype"` 32 | Columncomment string `json:"columncomment"` 33 | Columnkey string `json:"columnkey"` 34 | Extra string `json:"extra"` 35 | } 36 | 37 | func init() { 38 | flag.StringVar(&db_account, "acc", "root", "# Database account") 39 | flag.StringVar(&db_pwd, "pwd", "123123", "# Database password") 40 | flag.StringVar(&db_host, "host", "127.0.0.1", "# Database host") 41 | flag.StringVar(&db_port, "port", "3306", "# Database port") 42 | flag.StringVar(&db_name, "d", "", "# Database name") 43 | flag.StringVar(&path, "path", "./models", "# Structure preservation path") 44 | flag.StringVar(&tables, "t", "all", "# Table name formats such as - t user, rule, config") 45 | 46 | } 47 | 48 | func main(){ 49 | flag.Parse() 50 | if db_name ==""{ 51 | flag.Usage() 52 | return 53 | } 54 | tables = convtables(tables)//转换 55 | 56 | fmt.Println("数据库:",db_name) 57 | fmt.Println("数据库账号:",db_account) 58 | fmt.Println("数据库密码:",db_pwd) 59 | fmt.Println("结构体保存路径:",path) 60 | fmt.Println("指定数生成据表:",tables) 61 | fmt.Println("Automatic Struct Start ...") 62 | if checkpath(path){ 63 | fmt.Println("paPath irregularityth Example:'./models'") 64 | return 65 | } 66 | 67 | dataSourceName := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s",db_account,db_pwd,db_host,db_port,db_name) 68 | db, err := sql.Open("mysql", dataSourceName) 69 | 70 | if err!=nil{ 71 | fmt.Println("mysql connect err:",err) 72 | return 73 | } 74 | //获取所有表 75 | var sqls = "select table_name from information_schema.tables where table_schema=?" 76 | if tables != "all"{ 77 | sqls = fmt.Sprintf("select table_name from information_schema.tables where table_schema=? and table_name in (%s)",tables) 78 | } 79 | rows,err2 := db.Query(sqls,db_name) 80 | if err2!=nil{ 81 | fmt.Println("mysql query err:",err2) 82 | return 83 | } 84 | defer func() { 85 | if rows != nil { 86 | rows.Close() //可以关闭掉未scan连接一直占用 87 | } 88 | }() 89 | 90 | table := Dbtabels{} 91 | for rows.Next(){ 92 | err := rows.Scan(&table.Name) 93 | fmt.Println("正在生成表结构:",table.Name) 94 | if err != nil { 95 | fmt.Printf("Scan failed,err:%v", err) 96 | return 97 | } 98 | //获取单个表所有字段 99 | cloumn_sql := fmt.Sprintf("select column_name columnName, data_type dataType, column_comment columnComment, column_key columnKey, extra from information_schema.columns where table_name = '%s' and table_schema = (select database()) order by ordinal_position",table.Name) 100 | cloumns,err3:= db.Query(cloumn_sql) 101 | if err3!=nil{ 102 | fmt.Println("mysql 获取单个表所有字段 err:",err3) 103 | } 104 | defer func() { 105 | if cloumns != nil { 106 | cloumns.Close() //可以关闭掉未scan连接一直占用 107 | } 108 | }() 109 | struct_str :=fmt.Sprintf("type %s struct { \n",strFirstToUpper(table.Name)) 110 | column := Column{} 111 | for cloumns.Next(){ 112 | err := cloumns.Scan(&column.Columname,&column.Datatype,&column.Columncomment,&column.Columnkey,&column.Extra) 113 | //类型判断 114 | //开始拼接字符串 115 | if err != nil { 116 | fmt.Printf("Scan failed,err:%v", err) 117 | return 118 | } 119 | struct_str += " "+strFirstToUpper(column.Columname) 120 | if column.Datatype == "int" || column.Datatype =="tinyint"{ 121 | struct_str +=" int " 122 | }else if column.Datatype == "decimal"{ 123 | struct_str +=" float64 " 124 | }else{ 125 | struct_str +=" string " 126 | } 127 | 128 | if column.Extra != "auto_increment"{ 129 | struct_str += fmt.Sprintf("`xorm:\"comment('%s')\" json:\"%s\"` \n",column.Columncomment,column.Columname) 130 | }else{ 131 | struct_str += fmt.Sprintf("`xorm:\"not null pk autoincr comment('%s') INT(11)\" json:\"%s\"` \n",column.Columncomment,column.Columname) 132 | } 133 | 134 | } 135 | struct_str += "}" 136 | model_head := "package models \n\n" 137 | //导出文件 138 | body := model_head+struct_str 139 | filename:=fmt.Sprintf("%s/%s.go",path,table.Name) 140 | //创建文件夹 141 | error2 := os.MkdirAll(path, os.ModePerm) 142 | if error2 != nil{ 143 | fmt.Println("midkr path err:",error2) 144 | } 145 | err4:=ioutil.WriteFile(filename,[]byte(body),0666) 146 | if err4 != nil{ 147 | fmt.Println("写入文件错误:",err4) 148 | } 149 | } 150 | 151 | fmt.Println("End SUCCESS") 152 | } 153 | 154 | //首字母大写 155 | func strFirstToUpper(str string) string { 156 | var upperStr string 157 | vv := []rune(str) // 后文有介绍 158 | for i := 0; i < len(vv); i++ { 159 | if i == 0 { 160 | if vv[i] >= 97 && vv[i] <= 122 { // 后文有介绍 161 | vv[i] -= 32 // string的码表相差32位 162 | upperStr += string(vv[i]) 163 | } else { 164 | fmt.Println("Not begins with lowercase letter,") 165 | return str 166 | } 167 | } else { 168 | upperStr += string(vv[i]) 169 | } 170 | } 171 | return upperStr 172 | } 173 | 174 | //判断用户输入 175 | func checkpath(path string)bool{ 176 | a := strings.Split(path, "/") 177 | if len(a)>=2 && a[1] != ""{ 178 | return false 179 | }else{ 180 | return true 181 | } 182 | 183 | } 184 | 185 | //用户输入转换 186 | func convtables(tab string)string{ 187 | if tab=="all"{ 188 | return tab 189 | }else{ 190 | str_arr := strings.Split(tab, ",") 191 | var tabs string 192 | for _,v := range str_arr { 193 | if v!=""{ 194 | item := fmt.Sprintf("'%s',",v) 195 | tabs += item 196 | } 197 | } 198 | //'mall_account','mall_goods' 199 | return tabs[0:len(tabs)-1] 200 | } 201 | } 202 | -------------------------------------------------------------------------------- /.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | tables 52 | 53 | 54 | 55 | 56 | 58 | 59 | 69 | 70 | 71 | 72 | 73 | true 74 | DEFINITION_ORDER 75 | 76 | 77 | 78 | 79 | 80 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 |