modeltemplate.go 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. package modelgen
  2. import (
  3. "bytes"
  4. "errors"
  5. "fmt"
  6. "strings"
  7. "text/template"
  8. "github.com/tal-tech/go-zero/tools/modelctl/model"
  9. "github.com/tal-tech/go-zero/tools/modelctl/util"
  10. )
  11. type (
  12. Query struct {
  13. Rows string
  14. Args string
  15. Values string
  16. }
  17. Update struct {
  18. Rows string
  19. Values string
  20. }
  21. Template struct {
  22. Package string
  23. PrimaryKeyField string
  24. PrimaryKeyFieldCamel string
  25. PrimaryKeyType string
  26. ModelCamelWithLowerStart string
  27. ModelLowerSplitByPound string
  28. ModelCamelWithUpperStart string
  29. Fields string
  30. Abbr string
  31. WithCache bool
  32. Insert Query
  33. // 包含where语句
  34. Update Update
  35. }
  36. StructField struct {
  37. // 字段名称,下划线
  38. NameWithUnderline string
  39. // 字段名称,驼峰式,大写开头
  40. NameCamelWithUpperStart string
  41. // 字段数据类型
  42. DataType string
  43. // 字段注释
  44. Comment string
  45. // 是否为主键
  46. PrimaryKey bool
  47. }
  48. )
  49. const (
  50. fieldTemplateText = "{{.NameCamelWithUpperStart}} {{.DataType}} `db:\"{{.NameWithUnderline}}\" json:\"{{.NameWithUnderline}},omitempty\"` {{.Comment}}"
  51. modelTemplateText = `package {{.Package}}
  52. import (
  53. "strings"
  54. "time"
  55. "github.com/tal-tech/go-zero/core/stores/redis"
  56. "github.com/tal-tech/go-zero/core/stores/sqlx"
  57. "github.com/tal-tech/go-zero/service/shared/builderx"
  58. "github.com/tal-tech/go-zero/service/shared/cache"
  59. )
  60. var (
  61. {{.ModelCamelWithLowerStart}}QueryRows = strings.Join(builderx.FieldNames(&{{.ModelCamelWithUpperStart}}{}), ",")
  62. {{if .WithCache}}{{.ModelCamelWithLowerStart}}CachePrefix = "xjy#{{.ModelLowerSplitByPound}}#"
  63. {{.ModelCamelWithLowerStart}}Expire = 7 * 24 * 3600{{end}}
  64. )
  65. type (
  66. {{.ModelCamelWithUpperStart}}Model struct {
  67. {{if .WithCache}} *CachedModel{{else}}
  68. table string
  69. conn sqlx.SqlConn{{end}}
  70. }
  71. {{.ModelCamelWithUpperStart}} struct {
  72. {{.Fields}}
  73. }
  74. )
  75. func New{{.ModelCamelWithUpperStart}}Model(table string, conn sqlx.SqlConn{{if .WithCache}}, rds *redis.Redis{{end}}) *{{.ModelCamelWithUpperStart}}Model {
  76. {{if .WithCache}} return &{{.ModelCamelWithUpperStart}}Model{NewCachedModel(conn, table, rds)}
  77. {{else}}return &{{.ModelCamelWithUpperStart}}Model{table:table,conn:conn}{{end}}
  78. }
  79. func ({{.Abbr}} *{{.ModelCamelWithUpperStart}}Model) Insert(data *{{.ModelCamelWithUpperStart}}) error {
  80. querySql:="insert into "+{{.Abbr}}.table+" ({{.Insert.Rows}}) value ({{.Insert.Args}})"
  81. _, err := {{.Abbr}}.conn.Exec(querySql, {{.Insert.Values}})
  82. return err
  83. }
  84. func ({{.Abbr}} *{{.ModelCamelWithUpperStart}}Model) Update(data *{{.ModelCamelWithUpperStart}}) error {
  85. {{if .WithCache}}err := {{.Abbr}}.cleanCache(data.{{.PrimaryKeyField}})
  86. if err != nil {
  87. return err
  88. }
  89. querySql := "update " + {{.Abbr}}.table + " set {{.Update.Rows}}"
  90. _, err = {{.Abbr}}.conn.Exec(querySql,{{.Update.Values}} )
  91. return err
  92. {{else}}querySql := "update " + {{.Abbr}}.table + " set {{.Update.Rows}}"
  93. _, err := {{.Abbr}}.conn.Exec(querySql,{{.Update.Values}} )
  94. return err{{end}}
  95. }
  96. func ({{.Abbr}} *{{.ModelCamelWithUpperStart}}Model) FindOne({{.PrimaryKeyFieldCamel}} {{.PrimaryKeyType}})(*{{.ModelCamelWithUpperStart}},error){
  97. querySql:="select "+{{.ModelCamelWithLowerStart}}QueryRows+" from "+{{.Abbr}}.table+" where {{.PrimaryKeyFieldCamel}} = ? limit 1"
  98. var resp {{.ModelCamelWithUpperStart}}
  99. {{if .WithCache}}key := cache.FormatKey({{.ModelCamelWithLowerStart}}CachePrefix,{{.PrimaryKeyFieldCamel}})
  100. err := {{.Abbr}}.QueryRow(&resp, key, {{.ModelCamelWithLowerStart}}Expire, func(conn sqlx.Session, v interface{}) error {
  101. return conn.QueryRow(v, querySql, {{.PrimaryKeyFieldCamel}})
  102. })
  103. if err != nil {
  104. if err == sqlx.ErrNotFound {
  105. return nil, ErrNotFound
  106. }
  107. return nil, err
  108. }
  109. {{else}}err := {{.Abbr}}.conn.QueryRow(&resp, querySql, {{.PrimaryKeyFieldCamel}})
  110. if err != nil {
  111. if err == sqlx.ErrNotFound {
  112. return nil, ErrNotFound
  113. }
  114. return nil, err
  115. }{{end}}
  116. return &resp, nil
  117. }
  118. func ({{.Abbr}} *{{.ModelCamelWithUpperStart}}Model) DeleteById({{.PrimaryKeyFieldCamel}} {{.PrimaryKeyType}}) error {
  119. {{if .WithCache}}err := {{.Abbr}}.cleanCache({{.PrimaryKeyFieldCamel}})
  120. if err != nil {
  121. return err
  122. }
  123. querySql := "delete from " + {{.Abbr}}.table + " where {{.PrimaryKeyFieldCamel}} = ? "
  124. _, err = {{.Abbr}}.conn.Exec(querySql, {{.PrimaryKeyFieldCamel}})
  125. return err
  126. {{else}}querySql := "delete from " + {{.Abbr}}.table + " where {{.PrimaryKeyFieldCamel}} = ? "
  127. _, err := {{.Abbr}}.conn.Exec(querySql, {{.PrimaryKeyFieldCamel}})
  128. return err{{end}}
  129. }
  130. {{if .WithCache}}
  131. func ({{.Abbr}} *{{.ModelCamelWithUpperStart}}Model) cleanCache({{.PrimaryKeyFieldCamel}} {{.PrimaryKeyType}}) error {
  132. key := cache.FormatKey({{.ModelCamelWithLowerStart}}CachePrefix,{{.PrimaryKeyFieldCamel}})
  133. _, err := {{.Abbr}}.rds.Del(key)
  134. return err
  135. }
  136. {{end}}
  137. `
  138. )
  139. func generateModelTemplate(packageName, table string, fileds []*Field) (*Template, error) {
  140. list := make([]*StructField, 0)
  141. var containsPrimaryKey bool
  142. for _, item := range fileds {
  143. goType, ok := model.CommonMysqlDataTypeMap[item.Type]
  144. if !ok {
  145. return nil, errors.New(fmt.Sprintf("table:%v,the data type %v of mysql does not match", table, item.Type))
  146. }
  147. if !containsPrimaryKey {
  148. containsPrimaryKey = item.Primary == "PRI"
  149. }
  150. list = append(list, &StructField{
  151. NameWithUnderline: item.Name,
  152. NameCamelWithUpperStart: util.FmtUnderLine2Camel(item.Name, true),
  153. DataType: goType,
  154. Comment: item.Comment,
  155. PrimaryKey: item.Primary == "PRI",
  156. })
  157. }
  158. if !containsPrimaryKey {
  159. return nil, errors.New(fmt.Sprintf("table:%v,primary key does not exist", table))
  160. }
  161. var structBuffer, insertRowsBuffer, insertArgBuffer, insertValuesBuffer, updateRowsBuffer, updateValuesBuffer bytes.Buffer
  162. var primaryField *StructField
  163. for index, item := range list {
  164. out, err := convertField(item)
  165. if err != nil {
  166. return nil, err
  167. }
  168. structBuffer.WriteString(out + "\n")
  169. if !item.PrimaryKey {
  170. insertRowsBuffer.WriteString(item.NameWithUnderline)
  171. insertArgBuffer.WriteString("?")
  172. insertValuesBuffer.WriteString("data." + item.NameCamelWithUpperStart)
  173. updateRowsBuffer.WriteString(item.NameWithUnderline + "=?")
  174. updateValuesBuffer.WriteString("data." + item.NameCamelWithUpperStart)
  175. if index < len(list)-1 {
  176. insertRowsBuffer.WriteString(",")
  177. insertArgBuffer.WriteString(",")
  178. insertValuesBuffer.WriteString(",")
  179. updateRowsBuffer.WriteString(",")
  180. }
  181. updateValuesBuffer.WriteString(",")
  182. } else {
  183. primaryField = item
  184. }
  185. }
  186. updateRowsBuffer.WriteString(" where " + primaryField.NameWithUnderline + "=?")
  187. updateValuesBuffer.WriteString(" data." + primaryField.NameCamelWithUpperStart)
  188. modelSplitByPoundArr := strings.Replace(table, "_", "#", -1)
  189. templateStruct := Template{
  190. Package: packageName,
  191. PrimaryKeyField: primaryField.NameCamelWithUpperStart,
  192. PrimaryKeyFieldCamel: primaryField.NameWithUnderline,
  193. PrimaryKeyType: primaryField.DataType,
  194. ModelCamelWithLowerStart: util.FmtUnderLine2Camel(table, false),
  195. ModelLowerSplitByPound: modelSplitByPoundArr,
  196. ModelCamelWithUpperStart: util.FmtUnderLine2Camel(table, true),
  197. Fields: structBuffer.String(),
  198. Abbr: util.Abbr(table) + "m",
  199. Insert: Query{
  200. Rows: insertRowsBuffer.String(),
  201. Args: insertArgBuffer.String(),
  202. Values: insertValuesBuffer.String(),
  203. },
  204. Update: Update{
  205. Rows: updateRowsBuffer.String(),
  206. Values: updateValuesBuffer.String(),
  207. },
  208. }
  209. return &templateStruct, nil
  210. }
  211. func convertField(field *StructField) (string, error) {
  212. if strings.TrimSpace(field.Comment) != "" {
  213. field.Comment = "// " + field.Comment
  214. }
  215. tl, err := template.New("").Parse(fieldTemplateText)
  216. if err != nil {
  217. return "", err
  218. }
  219. buf := bytes.NewBufferString("")
  220. err = tl.Execute(buf, field)
  221. if err != nil {
  222. return "", err
  223. }
  224. return buf.String(), nil
  225. }