一、前提提要
1、ent框架:是一个操控数据库的orm框架,类似python中的sqlalchemy来操作数据库
2、据说非常适合处理各种复杂关系(我也不知道是真是假,不过好用是真的)
3、安装:go get entgo.io/ent/cmd/entc(如果不行 go install entgo.io/ent/cmd/ent@latest)
4、引用别人的一个概念:
(1)Schema:描述一个实体的定义以及他与其他实体的关系,类似python里用sqlalchemy创建的modul,就是数据表的一个描述
(2)Edges:实体与实体之间的关系称为edge
4、常用命令:
- 创建一个Schema:ent init --target ent/schema User(在当前目录下的,ent/schema目录下创建一个User.go文件,用于待会创建一个数据表)
- 生成代码:ent generate ./ent/schema
二、代码说明
1、运行:ent init --target ent/schema User 命令后,生成的User.go文件进行编辑
package schema
import (
"entgo.io/ent"
"entgo.io/ent/schema/field"
)
// User holds the schema definition for the User entity.
type User struct {
ent.Schema
}
// Fields of the User. 用户字段
func (User) Fields() []ent.Field {
return []ent.Field{
// 年龄整数
field.Int("age").Positive(),
// 姓名为字符串
field.String("name").Default("unknown"),
}
}
// Edges of the User.用户表关系
func (User) Edges() []ent.Edge {
return []ent.Edge{}
}
2、运行:ent generate ./ent/schema 生成代码,目录结构如下
ent
├── client.go
├── config.go
├── context.go
├── ent.go
├── migrate
│ ├── migrate.go
│ └── schema.go
├── predicate
│ └── predicate.go
├── schema // 这个就是用来描述表的目录,其他的都是自动生成的
│ └── user.go
├── tx.go
├── user
│ ├── user.go
│ └── where.go
├── user.go
├── user_create.go
├── user_delete.go
├── user_query.go
└── user_update.go
3、有表描述后,我们就要实例化到数据中,建立一个main包,中间创建一个main.go文件,手动执行后即可在mysql中创建一个User表
package main
import (
"fmt"
"go_ent_stu/dao" // 这个是我们新建一个dao目录,用来存对mysql所有操作的方法
"go_ent_stu/internal/ent"
_ "github.com/go-sql-driver/mysql"
)
func initMysql() {
username := "root"
password := "root"
address := "127.0.0.1:3306"
dbname := "test"
dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?parseTime=true", username, password, address, dbname)
var err error
// dao.Db:用于存放连接mysql后的client,在dao中做为全局存储,dao/client.go文件
dao.Db, err = ent.Open("mysql", dsn)
if err != nil {
fmt.Println("ent Open is err ", err)
}
}
// 建User表,创建了实体
func main() {
initMysql()
}
4、创建编写目录与文件,dao/client.go 存放全局都要用到连接mysql的client
package dao
import "go_ent_stu/internal/ent"
var (
Db *ent.Client
)
5、在dao目录下新建user/func_to_user.go文件,存放对mysql的操作
package user
import (
"context"
"fmt"
"go_ent_stu/dao"
"go_ent_stu/internal/ent"
"go_ent_stu/internal/ent/user"
)
// 增
func Insert() {
client := dao.Db
u, err := client.User.Create().SetAge(19).SetName("helloman").Save(context.Background())
if err != nil {
fmt.Println("client.User.Create err is ", err)
}
fmt.Println("U is ", u)
}
// 查
func Select() (*ent.User, error) {
client := dao.Db
u, err := client.User.Query().Where(user.NameEQ("helloman")).Only(context.Background())
// 有条件查的例子, 查询 年龄>=18 and 年龄<=30 的所有数据
// client.User.Query().Where(user.AgeGTE(18), user.AgeLTE(30)).All(context.Background())
if err != nil {
fmt.Println("client.User.Query err is ", err)
}
fmt.Println("查询成功")
return u, nil
}
// 改
func Update(test_user *ent.User) {
u, err := test_user.Update().SetAge(1000).Save(context.Background())
if err != nil {
fmt.Println("test_user.Update err is ", err)
}
fmt.Println("修改成功")
fmt.Println("update u is ", u)
}
// 删
func Delete(test_user *ent.User) {
client := dao.Db
err := client.User.DeleteOne(test_user).Exec(context.Background())
if err != nil {
fmt.Println("client.User.DeleteOne err is ", err)
}
fmt.Println("删除成功")
}
6、建好这些方法后,就可以通过main包下的main.go进行调用,实验
package main
import (
"fmt"
"go_ent_stu/dao"
"go_ent_stu/dao/user"
"go_ent_stu/internal/ent"
_ "github.com/go-sql-driver/mysql"
)
func initMysql() {
username := "root"
password := "root"
address := "127.0.0.1:3306"
dbname := "test"
dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?parseTime=true", username, password, address, dbname)
var err error
dao.Db, err = ent.Open("mysql", dsn)
if err != nil {
fmt.Println("ent Open is err ", err)
}
}
// 建User表,创建了实体
func main() {
initMysql()
// 增
user.Insert()
// 查
u, _ := user.Select()
// 改
user.Update(u)
// 删
user.Delete(u)
}
这些就解决了,对mysql的基本操作,但是对一些特殊需求这些知识量还不够,因此进行查询官方文档查看对应的api(可能需要梯子):https://entgo.io/