连接数据库

必要的包导入

import (
    "context"
    "database/sql"
    entsql "entgo.io/ent/dialect/sql"
    _ "go-aci"
    "log"
)

创建连接

db, err := sql.Open("aci", "SYSDBA:szoscar55@localhost:2003/OSRDB")
if err != nil {
log.Fatalf("failed opening connection to oscar: %v", err)
}
drv := entsql.OpenDB("oscar", db)
client := ent.NewClient(ent.Driver(drv))

数据类型

ent方言类型 数据库数据类型 go类型 备注
Int INT8 Int  
String VARCHAR String  
Float FLOAT8 float  
Bool BOOL bool  
Time TIMESTAMPTZ time  
Text TEXT String  
Bytes BLOB byte  

创建表结构

示例:

func (User) Fields() []ent.Field {
    // return nil
    return []ent.Field{
        field.Int("age").
            Positive(),
        field.String("name").
            Default("unknown"),
    }
}

数据迁移

CreateTable(client)
func CreateTable(client *ent.Client) {
    if err := client.Debug().Schema.Create(context.Background()); err != nil {
        log.Fatalf("failed creating schema resources: %v", err)
    }
}

添加数据

示例:

CreateUser(context.Background(), client.Debug())

func CreateUser(ctx context.Context, client *ent.Client) (*ent.User, error) {
    u, err := client.User.
        Create().
        SetAge(30).
        SetName("a8m").
        Save(ctx)
    if err != nil {
        return nil, fmt.Errorf("failed creating user: %w", err)
    }
    log.Println("user was created: ", u)
    return u, nil
}

查询数据

示例:

QueryUser(context.Background(), client.Debug())

func QueryUser(ctx context.Context, client *ent.Client) (*ent.User, error) {
    u, err := client.User.
        Query().
        Where(user.Name("a8m")).
        // `Only` fails if no user found,
        // or more than 1 user returned.
        Only(ctx)
    if err != nil {
        return nil, fmt.Errorf("failed querying user: %w", err)
    }
    log.Println("user returned: ", u)
    return u, nil
}

数据更新

示例:

UpdateUser(context.Background(), client.Debug())

func UpdateUser(ctx context.Context, client *ent.Client) (*ent.User, error) {
    n, err := client.User. // UserClient.
        Update().
        Where(
            user.Or(            // (age >= 30 OR name = "bar")
                user.AgeGT(30),
                user.Name("a8m"),
        SetName("foo").
        Save(ctx)
    fmt.Println(n)
    u, err := client.User.
        Query().
        Where(user.Name("foo")).
        // `Only` fails if no user found,
        // or more than 1 user returned.
        Only(ctx)
    return u, err
}

数据删除

示例:

DeleteUser(context.Background(), client.Debug())

func DeleteUser(ctx context.Context, client *ent.Client) error {
    var name string = "DeleteUser1"
    user1, err := client.User.
        Query().
        Where(user.Name(name)).
        // `Only` fails if no user found,
        // or more than 1 user returned.
        Only(ctx)
    if err != nil {
        fmt.Println(err)
        return fmt.Errorf("DeleteUser-Query failed: %w", err)
    }

    err = client.Debug().User.
        DeleteOne(user1).
        Exec(ctx)
    if err != nil {
        return fmt.Errorf("DeleteUser-DeleteOne failed: %w", err)
    }
    return nil
}

大对象操作

建表

示例:

// schema\testlob.go

func (Testlob) Fields() []ent.Field {
   return []ent.Field{
      field.String("name"),
      field.Bytes("tblob"),
      field.Text("tclob"),
   }
}

创建数据

示例:

CreateLob(context.Background(), client.Debug())

func CreateLob(ctx context.Context, client *ent.Client) (*ent.Testlob, error) {
    blobData := []byte("This is a BLOB data")
    clobData := "This is a CLOB data"
    u, err := client.Testlob.
        Create().
        SetName("this").
        SetTblob(blobData).
        SetTclob(clobData).
        Save(ctx)
    if err != nil {
        return nil, fmt.Errorf("failed CreateLob: %w", err)
    }
    log.Println("lob was created: ", u)
    return u, nil
}

查询数据

示例:

QueryLob(context.Background(), client.Debug())

func QueryLob(ctx context.Context, client *ent.Client) (*ent.User, error) {
    lob, err := client.Testlob.
        Query().
        Where(testlob.Name("this")).Only(ctx)
    if err != nil {
        log.Fatal(err)
    }

    if err != nil {
        return nil, fmt.Errorf("failed querying lob: %w", err)
    }
    log.Println("user returned: ", lob)
    return nil, nil
}

分页查询

用Limit和Offset来实现分页

示例:

QueryUser_page(context.Background(), client.Debug())

func QueryUser_page(ctx context.Context, client *ent.Client) error {
    idx := 0
    for i := 0; i <= 20; i++ {
        idx += i
        name := fmt.Sprintf("分页查询-%d", i)
        _, err := client.User.
            Create().
            SetAge(66).
            SetName(name).
            Save(ctx)
        if err != nil {
            log.Fatalf("QueryUser_singleTable_page-1 failed: %v", err)
        }
    }

    pageSize := 10
    page := 2 // 第 2 页
    offset := (page - 1) * pageSize

    users, err := client.User.
        Query().
        Limit(pageSize).
        Offset(offset).
        All(context.Background())
    if err != nil {
        log.Fatal(err)
    }

    // 输出查询结果
    for _, user := range users {
        log.Printf("User ID: %d, Name: %s", user.ID, user.Name)
    }
    return nil
}