重要的参考资料
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 }
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插入数据 避免主键冲突 =========== }
~~~