ent裸SQL执行

ent快速上手一文中介绍了如何在ent框架内使用ORM思想操作数据库,本文讲述下如何在ent框架下执行裸SQL语句。

ent通过引入sql/execquery的feature flag来支持裸SQL执行,这样可以绕过繁琐的relational mapping部分。

详见:https://entgo.io/docs/feature-flags#sql-raw-api

ent裸SQL执行使用的client需要多封装一层,示例如下:

package main

import (
	"context"
	"entgo.io/ent/dialect/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"github.com/realcp1018/tinylog"
	"os"
	"test/ent"
	"test/ent/car"
	"test/ent/user"
	"time"
)

var Logger = tinylog.NewStreamLogger(tinylog.INFO)

func main() {
	dsnStr := "user:password@tcp(host:port)/<database>?parseTime=True"
	drv, err := sql.Open("mysql", dsnStr)
	if err != nil {
		Logger.Error(err.Error())
		os.Exit(1)
	}
	// Get the underlying sql.DB object of the driver.
	db := drv.DB()
	db.SetMaxIdleConns(10)
	db.SetMaxOpenConns(10)
	db.SetConnMaxLifetime(time.Hour)
    // 相比于直接Open DSN获取连接,封装entgo.io/ent/dialect/sql.*DB显然更加适合生产环境,即有连接池的支持,又可以支持执行裸SQL
	client := ent.NewClient(ent.Driver(drv))
	//client, _ := ent.Open("mysql", dsnStr)
	defer client.Close()
	_ = RawSQLQueryUser(context.Background(), client)
}

func RawSQLQueryUser(ctx context.Context, client *ent.Client) error {
	q := "select * from users"
	result, err := client.QueryContext(ctx, q)
	if err != nil {
		return err
	}
    // QueryContext
	for result.Next() {
		myuser := new(ent.User)
		_ = result.Scan(&myuser.ID, &myuser.Name, &myuser.Age, &myuser.Address)
		fmt.Println(myuser.ID, myuser.Name, myuser.Age, myuser.Address)
	}
	return nil
}

dialect/sql就是针对标准库database/sql的封装,目前dialect/sql只支持QueryContext和ExecContext两个方法,所以查询单条SQL也只能通过result.Next来Scan获取结果。

标准库中有关于QueryContext的说明和示例,参考:https://pkg.go.dev/database/sql#DB.QueryContext

posted @ 2022-09-01 19:02  realcp1018  阅读(1084)  评论(0编辑  收藏  举报