SQLBoiler入门指导1-最好用的Go ORM框架
SQLBoiler官方文档翻译–最好用的Go ORM框架
SQLBoiler 是一个根据数据库表生成对应的 Go ORM 代码的工具。
它是一个数据库先行的 ORM 框架,也就是说你需要先设计你的数据库,而不是像 gorm 那样先设计 struct。
1. 环境
这里使用 MySQL 作为数据库,其他数据库配置和依赖可能会有所不同。
环境要求 :
Go 1.13以上
表名列名使用蛇形命名法snake_case
蛇形命名法
特点
全部小写 :所有字母都使用小写。
单词间隔 :单词之间使用下划线(_)来分隔。
数据库表结构
1 2 3 4 5 6 7 8 9 CREATE TABLE `user ` ( `id` bigint (0 ) UNSIGNED NOT NULL AUTO_INCREMENT, `username` varchar (64 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL , `password` varchar (64 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL , `nick_name` varchar (32 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' , `created_at` datetime(0 ) NOT NULL DEFAULT CURRENT_TIMESTAMP (0 ), `updated_at` datetime(0 ) NOT NULL DEFAULT CURRENT_TIMESTAMP (0 ) ON UPDATE CURRENT_TIMESTAMP (0 ), PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic ;
第一步:下载安装代码生成插件,
1 2 3 4 5 6 7 # Go 1.16 和之后: go install github.com/volatiletech/sqlboiler/v4@latest go install github.com/volatiletech/sqlboiler/v4/drivers/sqlboiler-mysql@latest # Go 1.15 和之前: GO111MODULE=on go get -u -t github.com/volatiletech/sqlboiler/v4 GO111MODULE=on go get github.com/volatiletech/sqlboiler/v4/drivers/sqlboiler-mysql
注:如果使用别的数据库需要把上面的mysql改成对应数据库的名字(如果支持的话)。
第二步:安装依赖
1 2 go get github.com/volatiletech/sqlboiler/v4 go get github.com/volatiletech/null/v8
第三步:配置文件
SQLBoiler 会自动识别根路径下的 sqlboiler.toml 配置文件。内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 wipe = true no-tests = true add-global-variants = true add-panic-variants = true no-context = true [mysql] dbname = "dbname" host = "127.0.0.1" user = "root" pass = "root" sslmode = "false"
注意:如果使用其他数据库可能配置会有区别,详细的配置项可以看官方文档 。
第四步:生成代码
在命令行输入下面命令即可生成图片models目录中的代码:
2. 增删改查
2.1. 设置数据库源
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 package mainimport ( "database/sql" "fmt" _ "github.com/go-sql-driver/mysql" "github.com/volatiletech/sqlboiler/v4/boil" "github.com/volatiletech/sqlboiler/v4/queries/qm" "log" "sqlboiler-learning/start/models" )func main () { dsn := "root:guowei.gongPWD2024@tcp(127.0.0.1:3306)/learning?parseTime=True" db, err := sql.Open("mysql" , dsn) if err != nil { log.Fatal(err) } defer db.Close() boil.SetDB(db) }
2.2. insert
1 2 3 4 5 6 7 8 9 func InsertUserDemo () { user := models.User{ Username: "username1" , Password: "123456" , NickName: "nickName1" , } user.InsertGP(boil.Infer()) fmt.Printf("%+v" , user) }
查看输出 1 {ID:7 Username:username1 Password:123456 NickName:nickName1 CreatedAt:2021-07-18 13:34:16.3409056 +0000 UTC UpdatedAt:2021-07-18 13:34:16.3409056 +0000 UTC R:<nil> L:{}}
可以看到插入操作只需一行代码 user.InsertGP(boil.Infer())
即可,插入后会自动设置 ID
、 CreateAt
和 UpdatedAt
等自动生成的值。其中 boil.Infer()
是智能选择插入字段,Go 零值字段不会被选中,但是插入后会根据数据库生成的值设置这些字段(如自增主键,默认账,更新时间,创建时间等)。
InsertGP()
的 GP
表示使用全局数据源(G)和不返回 error
(P,当返回 error
不为 nil
时直接 panic
),R
和 L
字段是 SQLBoiler 插件自动生成现在可以先忽略。
2.3. delete
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 func DeleteUserDemo () { user := models.User{ID: 1 } count := user.DeleteGP() fmt.Println(count) users := models.Users().AllGP() count = users.DeleteAllGP() fmt.Println(count) count, _ = models.Users(models.UserWhere.Username.EQ("username1" )).DeleteAllG() fmt.Println(count) }
删除操作也需要一行,可以根据 User struct
进行删除,根据 UserSlice
批量删除,也可以根据条件
进行删除,返回值是成功删除的行数。
2.4. select
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 func SelectUserDemo () { users := models.Users(qm.Select(models.UserColumns.ID, models.UserColumns.NickName), models.UserWhere.Username.EQ("username1" )).AllGP() fmt.Println(users) count := models.Users(models.UserWhere.Username.EQ("username1" )).CountGP() fmt.Println(count) user, err := models.FindUserG(1 ) if err == sql.ErrNoRows { } fmt.Println(user) }
可以根据条件查询记录,查询数量,还可以根据主键查询。注意 FinUserG()
在查询不到记录的时候会返回 sql.ErrNoRows
,所以最好判断一下。
qm.Select()
可以用来指定查询的列。
2.5. update
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 func UpdateUserDemo () { user := models.User{ID: 1 , NickName: "nickName1001" } count := user.UpdateGP(boil.Whitelist(models.UserColumns.NickName)) fmt.Println(count) users := models.Users().AllGP() count = users.UpdateAllGP(models.M{models.UserColumns.NickName: "updateAllNickName" }) fmt.Println(count) count, _ = models.Users(models.UserWhere.NickName.EQ("updateAllNickName" )). UpdateAllG(models.M{models.UserColumns.NickName: "updateAllNickName2" }) fmt.Println(count) }
与 Delete 操作类似,可以根据 User struct
进行更新,也可以根据 UserSlice
批量更新,还可以根据条件
进行更新。
这里需要注意,在根据 User struct
进行更新时,最好使用 boil.Whitelist()
指定更新的字段,因为如果使用 boil.Infer()
就算是零值也会进行更新。
models.M{}
表示更新的字段和对应的值。