• 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 
    ",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 
    ",result.RowsAffected()) // batch insert rows affected:2
    
        // =========== 执行原生SQL插入数据 避免主键冲突 ===========
    
    
    
    }
    go-pg_test.go

    ~~~

  • 相关阅读:
    从内积的观点来看线性方程组
    《线性规划》(卢开澄,卢华明) 例2.1
    斐波那契数列
    共几只桃子
    计算 $s=1+(1+2)+(1+2+3)+cdots+(1+2+3+cdots+n)$
    【★】路由环路大总结!
    Apache与Tomcat有什么关系和区别
    Apache与Tomcat有什么关系和区别
    逻辑卷、物理卷、卷组 的关系
    逻辑卷、物理卷、卷组 的关系
  • 原文地址:https://www.cnblogs.com/paulwhw/p/15464648.html
Copyright © 2020-2023  润新知