ä¸ÂãÂÂ为ä»Âä¹Âè¦Â使ç¨gorm-gen
æÂ¥çÂÂæÂÂå®Âä½Âç±»åÂÂæ¥询
-
1ãÂÂæ ¹æ®
gorm
å®Âç½Âå°åÂÂï¼Âæ£常çÂÂÃ¥ÂÂæ³Âæ¯å ÂÃ¥ÂÂæ°æ®模åÂÂ,ç¶åÂÂç±æ°æ®模åÂÂèªå¨åÂÂæÂ¥çÂÂæÂÂå°æ°æ®åºÂä¸Â,ä½Âæ¯è¿Âæ ·çÂÂå·¥ä½ÂéÂÂä¼Âæ¯Âè¾Â大,对äºÂÃ¥ÂÂÃ¥ÂÂ端çÂÂ人æ¥说é½çÂÂæÂÂsql
è¯ÂÃ¥ÂÂ¥,æ£常æ¥说é½æ¯å Âèª己æÂÂå¨åÂÂ建表,å©ç¨工堷å°Â表åÂÂ段åÂÂæÂ¥å°项ç®å®Âä½Âç±»ä¸Âï¼Âä¹ÂÃ¥ÂÂæÂÂå°±åÂÂè¿Âä¸Â个è¿Âæ ·çÂÂ工堷ï¼Â对äºÂå°Â项ç®æ¥说é½è½满足 -
2ãÂÂ使ç¨ä¸Âé¢çÂÂæ¹å¼Âå¨项ç®ä¸ÂÃ¥ÂÂåºçÂÂ代ç Â大æ¦Âæ¯å¦Âæ¤ï¼Âè¿Âæ ·å¦ÂæÂÂæ°æ®åºÂÃ¥ÂÂ段æ¹äºÂ,ç¨ÂåºÂæ¯æ æ³Âè¯Âå«åºæÂ¥ï¼Âä¸Âè½å¾Â好çÂÂè§Âé¿éÂÂ误
-
3ãÂÂ
gorm-gen
Ã¥ÂÂ好å¯以满足è¿Â个éÂÂæ±Âï¼ÂÃ¥ÂÂåºçÂÂ代ç Âæ´好çÂÂç»´æ¤ï¼Âæ¯Âå¦Âä¸Âé¢çÂÂ代ç Â
äºÂãÂÂå¨项ç®ä¸ÂéÂ
Âç½®gorm-gen
æÂ¥çÂÂæÂÂsql
æÂÂä½Â
-
1ãÂÂæÂÂå¨æ°åÂÂ建表
DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` bigint UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主é®', `username` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT 'ç¨æ·åÂÂ', `age` int UNSIGNED NOT NULL COMMENT 'å¹´é¾Â', `password` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT 'å¯Âç Â', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Ã¥ÂÂ建æ¶é´', `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'æ´æ°æ¶é´', `deleted_at` timestamp NULL DEFAULT NULL COMMENT '软å é¤æ¶é´', `phone` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'æÂÂæºå·ç Â', PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-
2ãÂÂæ ¹æ®å®Âç½ÂæÂ¥å®Â裠ä¾ÂèµÂÃ¥ÂÂ
go get -u gorm.io/gen go get -u gorm.io/driver/mysql
-
3ãÂÂå¨项ç®çÂÂæ ¹ç®å½Âä¸ÂÃ¥ÂÂ建ä¸Â个
generate.go
çÂÂæÂÂ件package main import ( "fmt" "gorm.io/driver/mysql" "gorm.io/gen" "gorm.io/gen/field" "gorm.io/gorm" "strings" ) const dsn = "root:123456@(localhost:3306)/test001?charset=utf8mb4&parseTime=True&loc=Local" // Case2Camel ä¸ÂÃ¥ÂÂ线转驼峰(大驼峰) func Case2Camel(name string) string { name = strings.Replace(name, "_", " ", -1) // æ ¹æ®_æÂ¥æ¿æ¢æ name = strings.Title(name) // å ¨é¨大å return strings.Replace(name, " ", "", -1) // å é¤空格 } // LowerCamelCase 转æ¢为å°Â驼峰 func LowerCamelCase(name string) string { name = Case2Camel(name) return strings.ToLower(name[:1]) + name[1:] } func main() { var tableName string fmt.Print("请è¾Â堥表åÂÂ,å¦ÂæÂÂä¸Âè¾Âå ¥å°Âå ¨é¨åÂÂæÂ¥æ°æ®åºÂ:") if _, err := fmt.Scanln(&tableName); err != nil { fmt.Println("没æÂÂè¾Â堥表åÂÂå°Âå ¨é¨åÂÂæÂ¥æ°æ®åºÂ", err.Error()) } var fileName = Case2Camel(tableName) // 转为é¦ÂÃ¥ÂÂç®大å fmt.Println(fileName) // è¿ÂæÂ¥æ°æ®庠db, err := gorm.Open(mysql.Open(dsn)) if err != nil { panic(fmt.Errorf("cannot establish db connection: %w", err)) } // æÂÂé çÂÂæÂÂå¨å®Âä¾ g := gen.NewGenerator(gen.Config{ // ç¸对æ§è¡Â`go run`æ¶çÂÂè·¯å¾Â, ä¼Âèªå¨åÂÂ建ç®彠OutPath: "./dao", //curd代ç ÂçÂÂè¾Âåº路徠ModelPkgPath: "./model", //model代ç ÂçÂÂè¾Âåº路徠// WithDefaultQuery çÂÂæÂÂé»Â认æ¥询ç»ÂæÂÂä½Â(ä½Â为堨å±ÂÃ¥ÂÂéÂÂ使ç¨), å³`Q`ç»ÂæÂÂä½ÂÃ¥ÂÂå ¶åÂÂ段(Ã¥ÂÂ表模åÂÂ) // WithoutContext çÂÂæÂÂ没æÂÂcontextè°Âç¨éÂÂå¶çÂÂ代ç Âä¾Âæ¥询 // WithQueryInterface çÂÂæÂÂinterfaceå½¢å¼ÂçÂÂæ¥询代ç Â(å¯导åº), å¦Â`Where()`æ¹æ³Âè¿ÂÃ¥ÂÂçÂÂå°±æ¯ä¸Â个å¯导åºçÂÂæÂ¥å£类å Mode: gen.WithDefaultQuery | gen.WithoutContext | gen.WithQueryInterface, // 表åÂÂ段å¯为 null å¼æ¶, 对åºÂç»Âä½ÂÃ¥ÂÂ段使ç¨æÂÂéÂÂç±»å FieldNullable: false, // generate pointer when field is nullable // 表åÂÂ段é»Â认å¼ä¸Â模åÂÂç»ÂæÂÂä½ÂÃ¥ÂÂ段é¶å¼ä¸Âä¸Âè´çÂÂÃ¥ÂÂ段, å¨æÂÂå ¥æ°æ®æ¶éÂÂè¦ÂèµÂå¼该åÂÂ段å¼为é¶å¼çÂÂ, ç»ÂæÂÂä½ÂÃ¥ÂÂ段须æ¯æÂÂéÂÂç±»åÂÂæÂÂè½æÂÂÃ¥ÂÂ, å³`FieldCoverable:true`é Âç½®ä¸ÂçÂÂæÂÂçÂÂç»ÂæÂÂä½ÂÃ¥ÂÂ段. // å 为å¨æÂÂå ¥æ¶éÂÂå°åÂÂ段为é¶å¼çÂÂä¼Â被GORMèµÂäºÂé»Â认å¼. å¦ÂÃ¥ÂÂ段`age`表é»Â认å¼为10, å³使你æ¾å¼Â设置为0æÂÂÃ¥ÂÂä¹Âä¼Â被GORM设为10æÂÂ交. // å¦ÂæÂÂ该åÂÂ段没æÂÂä¸Âé¢æÂÂå°çÂÂæÂÂå ¥æ¶èµÂé¶å¼çÂÂç¹æ®ÂéÂÂè¦Â, Ã¥ÂÂÃ¥ÂÂ段为éÂÂæÂÂéÂÂç±»åÂÂ使ç¨起æÂ¥ä¼Âæ¯Âè¾Âæ¹便. FieldCoverable: false, // generate pointer when field has default value, to fix problem zero value cannot be assign: https://gorm.io/docs/create.html#Default-Values // 模åÂÂç»ÂæÂÂä½ÂÃ¥ÂÂ段çÂÂæ°åÂÂç±»åÂÂçÂÂ符å·表示æ¯å¦ä¸Â表åÂÂ段çÂÂä¸Âè´, `false`æÂÂ示é½ç¨æÂÂ符åÂ፱Ȍ FieldSignable: false, // detect integer field's unsigned type, adjust generated data type // çÂÂæ gorm æ Âç¾çÂÂÃ¥ÂÂ段索å¼Âå±Âæ§ FieldWithIndexTag: false, // generate with gorm index tag // çÂÂæ gorm æ Âç¾çÂÂÃ¥ÂÂ段类åÂÂå±Âæ§ FieldWithTypeTag: true, // generate with gorm column type tag }) // 设置ç®栠db g.UseDB(db) // èªå®Âä¹ÂÃ¥ÂÂ段çÂÂæ°æ®类å // ç»Âä¸Âæ°åÂÂç±»åÂÂ为int64,堼容protobufÃ¥ÂÂthrift dataMap := map[string]func(detailType gorm.ColumnType) (dataType string){ "tinyint": func(detailType gorm.ColumnType) (dataType string) { return "int64" }, "smallint": func(detailType gorm.ColumnType) (dataType string) { return "int64" }, "mediumint": func(detailType gorm.ColumnType) (dataType string) { return "int64" }, "bigint": func(detailType gorm.ColumnType) (dataType string) { return "int64" }, "int": func(detailType gorm.ColumnType) (dataType string) { return "int64" }, "timestamp": func(detailType gorm.ColumnType) (dataType string) { return "LocalTime" }, // èªå®Âä¹Âæ¶é´ "decimal": func(detailType gorm.ColumnType) (dataType string) { return "Decimal" }, // éÂÂé¢Âç±»åÂÂå ¨é¨转æ¢为第ä¸Âæ¹åºÂ,github.com/shopspring/decimal } // è¦Âå ÂäºÂ`ApplyBasic`æ§衠g.WithDataTypeMap(dataMap) // èªå®Âä¹Â模åÂÂç»Âä½ÂÃ¥ÂÂ段çÂÂæ Âç¾ // å°Âç¹å®ÂÃ¥ÂÂ段åÂÂç json æ Âç¾å ä¸Â`string`å±Âæ§,å³ MarshalJSON æ¶该åÂÂ段ç±æ°åÂÂç±»åÂÂ转æÂÂÃ¥ÂÂ符串类å jsonField := gen.FieldJSONTagWithNS(func(columnName string) (tagContent string) { toStringField := `id, ` if strings.Contains(toStringField, columnName) { return columnName + ",string" } else if strings.Contains(`deleted_at`, columnName) { return "-" } return LowerCamelCase(columnName) // ä¸ÂÃ¥ÂÂ线转å°Â驼峰 }) // å°ÂéÂÂé»Â认åÂÂ段åÂÂçÂÂÃ¥ÂÂ段å®Âä¹Â为èªå¨æ¶é´æ³åÂÂ软å é¤åÂÂ段; // èªå¨æ¶é´æ³é»Â认åÂÂ段åÂÂ为:`updated_at`ãÂÂ`created_at, 表åÂÂ段æ°æ®类åÂÂ为: INT æ DATETIME // 软å é¤é»Â认åÂÂ段åÂÂ为:`deleted_at`, 表åÂÂ段æ°æ®类åÂÂ为: DATETIME autoUpdateTimeField := gen.FieldGORMTag("updated_at", func(tag field.GormTag) field.GormTag { return map[string]string{ "column": "updated_at", "comment": "æ´æ°æ¶é´", } }) autoCreateTimeField := gen.FieldGORMTag("created_at", func(tag field.GormTag) field.GormTag { return map[string]string{ "column": "created_at", "comment": "Ã¥ÂÂ建æ¶é´", } }) softDeleteField := gen.FieldType("deleted_at", "gorm.DeletedAt") // 模åÂÂèªå®Âä¹ÂéÂÂ项绠fieldOpts := []gen.ModelOpt{jsonField, autoCreateTimeField, autoUpdateTimeField, softDeleteField} //fieldOpts := []gen.ModelOpt{jsonField, softDeleteField} // Ã¥ÂÂ建模åÂÂçÂÂç»ÂæÂÂä½Â,çÂÂæÂÂæÂÂ件å¨ model ç®å½Â; å ÂÃ¥ÂÂ建çÂÂç»ÂæÂÂä¼Â被åÂÂé¢åÂÂ建çÂÂè¦Âç // è¿ÂéÂÂÃ¥ÂÂ建个å«模åÂÂä» ä» æ¯为äºÂæ¿å°`*generate.QueryStructMeta`ç±»åÂÂ对象ç¨äºÂÃ¥ÂÂé¢çÂÂ模åÂÂå ³èÂÂæÂÂä½Â丠//User := g.GenerateModel("user") // å¦ÂæÂÂä¼ éÂÂäºÂ表åÂÂçÂÂæ¶åÂÂå°±åÂÂçÂŒÂÂ建åÂÂçÂÂ表 if tableName != "" { //allModel := g.GenerateAllTable(fieldOpts...) allModel := g.GenerateModelAs(tableName, fileName, fieldOpts...) // Ã¥ÂÂ建æÂÂå ³èÂÂ堳系çÂÂ模åÂÂæÂÂ件 // å¯以ç¨äºÂæÂÂå®Âå¤Âé® //Score := g.GenerateModel("score", // append( // fieldOpts, // // user ä¸Â对夠address å ³èÂÂ, å¤Âé®`uid`å¨ address 表丠// gen.FieldRelate(field.HasMany, "user", User, &field.RelateConfig{GORMTag: "foreignKey:UID"}), // )..., //) // Ã¥ÂÂ建模åÂÂçÂÂæ¹æ³Â,çÂÂæÂÂæÂÂ件å¨ query ç®å½Â; å ÂÃ¥ÂÂ建ç»ÂæÂÂä¸Âä¼Â被åÂÂÃ¥ÂÂ建çÂÂè¦Âç //g.ApplyBasic(User) g.ApplyBasic(allModel) } else { allModel := g.GenerateAllTable(fieldOpts...) g.ApplyBasic(allModel...) } g.Execute() }
-
4ãÂÂå¨
utils
æÂÂ件夹ä¸ÂÃ¥ÂÂ建ä¸Â个db.go
çÂÂæÂÂ件,è¿Â个å°æ¹æ¯è¿ÂæÂ¥æ°æ®åºÂçÂÂï¼Âå Âè¿Âè¡Âä¸Âé¢çÂÂæÂÂ件æÂÂä¼ÂçÂÂæÂÂdao
æÂÂ件const dsn = "root:123456@(localhost:3306)/test001?charset=utf8mb4&parseTime=True&loc=Local" var DB = dao.Query{} func InitDB() { db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{ Logger: logger.Default.LogMode(logger.Info), DisableForeignKeyConstraintWhenMigrating: true, // èªå¨åÂÂ建表çÂÂæ¶åÂÂä¸ÂÃ¥ÂÂ建å¤Âé® NamingStrategy: schema.NamingStrategy{ // èªå¨åÂÂ建表æ¶åÂÂ表åÂÂçÂÂé Âç½® SingularTable: true, }, }) if err != nil { panic(err) } // è¿Âè¡Âå ³è dao.SetDefault(db) q := dao.Q DB = *q } func init() { InitDB() }
-
5ãÂÂå¯以æ£常使ç¨å 置å°Â裠好çÂÂæ¹æ³ÂäºÂï¼Âæ¬æ¡Âä¾Âå°åÂÂ