├── 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 |
5 |
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 |
9 |
10 |
11 |
12 |
13 |
14 |
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 |
57 |
58 |
59 |
69 |
70 |
71 |
72 |
73 | true
74 | DEFINITION_ORDER
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
--------------------------------------------------------------------------------