go-pg库操作PostgreSQL小结

重要的参考资料

GO-PG Golang Postgre ORM *** 这里有详细的关于ORM操作的需求

PostgreSQL client and ORM for Go

自己做的练习

 

package gp_gp_tests

import (
    "github.com/go-pg/pg/v10"
    "time"
)

// DataBase的配置
type DatabaseConfig struct {
    URL                    string `yaml:"url"`
    ConnMaxLifetimeSeconds int    `yaml:"conn_max_lifetime_sec"`
    MaxOpenConns           int    `yaml:"max_open_conns"`
    MinIdleConns           int    `yaml:"min_idle_conns"`
    MaxRetries             int    `yaml:"max_retries"`
}

const defaultDBConnMaxRetries = 5

type DBService struct {
    *pg.DB
}

func InitDBService(dbCfg *DatabaseConfig) (*pg.DB, string, error) {
    // 1: 根据postgre的链接信息,生成一个 Options 对象
    opt, err := pg.ParseURL(dbCfg.URL)
    if err != nil {
        return nil, "", err
    }

    // 2:这里给 Options对象设置 链接、链接池 相关的参数~~~最长链接时间、最小空闲链接数、链接池最大链数(即链接池的大小)、最大重试次数~
    // 最大链接时间
    opt.MaxConnAge = time.Second * time.Duration(dbCfg.ConnMaxLifetimeSeconds)
    // 最小的空闲链接数
    opt.MinIdleConns = dbCfg.MinIdleConns
    // 链接池的最大连接数
    opt.PoolSize = dbCfg.MaxOpenConns
    // 最大retry次数
    if dbCfg.MaxRetries == 0 {
        opt.MaxRetries = defaultDBConnMaxRetries
    } else {
        opt.MaxRetries = dbCfg.MaxRetries
    }

    // 3: 通过 Options 对象生成DB对象~最终业务代码中用的是DB对象,里面有一个 newConnPool 方法用来设置链接池的~
    db := pg.Connect(opt)
    // 获取 version 信息
    var dbVersion string
    _, err = db.QueryOne(pg.Scan(&dbVersion), "select version()")
    if err != nil {
        return nil, "", err
    }
    return db, dbVersion, nil
}
init_db.go
package gp_gp_tests

import (
    "fmt"
    "github.com/go-pg/pg/v10/orm"
    "testing"
    "time"
)

// user_info表
/*
    create table user_info
(
    user_id                 varchar(32) not null
        constraint user_info_pkey
            primary key,
    user_name               varchar(32) not null,
    age                     smallint not null,
    updated                 timestamp default now(),
    created                 timestamp default now()
);
*/

type UserInfoModel struct {
    tableName struct{}  `pg:"user_info"`
    UserID    string    `json:"user_id" pg:"user_id,pk"`  // 使用ORM建表后是text类型
    UserName  string    `json:"user_name" pg:"user_name"` // 使用ORM建表后是text类型
    Age       int8      `json:"age" pg:"age"`             // 使用ORM建表后是smallint类型
    Updated   time.Time `json:"updated" pg:"updated"`     // 使用ORM建表后不设置default!!!
    Created   time.Time `json:"created" pg:"created"`     // 使用ORM建表后不设置default!!!
}

func (u *UserInfoModel) TableName() string {
    return "user_info"
}

const (
    // 数据库链接及链接池相关配置
    pgURL              = "postgresql://postgres:password@127.0.0.1:5433/whw_test_db?sslmode=disable"
    connMaxLifetimeSec = 3600
    maxOpenConns       = 100
    minIdleConns       = 10
    maxRetries         = 5
)

// 测试数据库链接 &
func TestDBInit(t *testing.T) {
    // ==================================== 初始化数据库 ====================================================
    dbCfg := DatabaseConfig{
        URL:                    pgURL,
        ConnMaxLifetimeSeconds: connMaxLifetimeSec,
        MaxOpenConns:           maxOpenConns,
        MinIdleConns:           minIdleConns,
        MaxRetries:             maxRetries,
    }
    // init db
    db, dbVersion, err := InitDBService(&dbCfg)
    if err != nil {
        fmt.Println("init DB Error: ", err)
        panic(err)
    }
    // close db
    defer db.Close()
    fmt.Println("db: ", db, "dbVersion: ", dbVersion)
    // ==================================== 根据model创建表/删除表(实际建议使用原生SQL做) =========================
    // =========== 创建表 ===========
    // TODO 注意,使用ORM创建的表,字符串类型都是 text类型!如果是int的话默认是bigint类型!!!实际上还是建议根据实际使用原生SQL创建表!!
    models := []interface{}{
        // 声明类型~~
        (*UserInfoModel)(nil),
    }
    for _, model := range models {
        // TODO 如果是一张表的话,里面的model可以用 &UserInfoModel{} 代替~
        err = db.Model(model).CreateTable(&orm.CreateTableOptions{
            IfNotExists: true,
        })
        if err != nil {
            fmt.Println("创建表 ", model, "raise error: ", err)
            panic(err)
        }
    }
    // =========== 删除表 ===========
    /*
        for _, model := range models{
            err = db.Model(model).DropTable(&orm.DropTableOptions{
                IfExists: true,
                Cascade: true,
            })
            if err != nil{
                fmt.Println("删除表 ", model, "raise error: ", err)
                panic(err)
            }
        }
    */

    // ==================================== insert 操作 ================================================
    // =========== 插入单条数据 ===========
    user1 := UserInfoModel{
        UserID: "xxx1232",
        UserName: "whw1",
        Age: 22,
    }
    result, err := db.Model(&user1).Insert()
    if err != nil{
        panic(err)
    }
    fmt.Printf("single insert rows affected:%d \n",result.RowsAffected()) // single insert rows affected:1

    // =========== 插入多条数据 ===========
    userList := []UserInfoModel{
        {
            UserID: "xxdsx555",
            UserName: "whw12",
            Age: 22,
        },
        {
            UserID: "xxdsx5awd55",
            UserName: "whw22",
            Age: 23,
        },
    }
    result, err = db.Model(&userList).Insert()
    if err != nil{
        panic(err)
    }
    fmt.Printf("batch insert rows affected:%d \n",result.RowsAffected()) // batch insert rows affected:2

    // =========== 执行原生SQL插入数据 避免主键冲突 ===========



}
go-pg_test.go

~~~

posted on 2021-10-26 10:33  江湖乄夜雨  阅读(648)  评论(0编辑  收藏  举报