连接数据库
Go驱动提供了如下的方法用于生成一个数据库连接对象。
func Open(driverName, dataSourceName string) (*DB, error)
参数说明:
- driverName为驱动的名称,数据库的驱动名称为"opengauss",兼容"postgres。
- dataSourceName为连接的数据源,支持DSN和URL两种:
- DSN格式:key1 = value1 key2 = value2 …,每组关键字间使用空格隔开,等号左右的空格是可选的。
- URL格式:driverName://[userspec@][hostspec][/dbname][?paramspec]
其中,driverName为驱动名称,数据库的驱动名称为“opengauss”,兼容“postgres”,“postgresql”。
userspec表示user[:password],需要注意的是使用URL进行连接时,密码中不可包含URL串中的分隔符。如果密码中包含分隔符的话,建议采用DSN格式。
hostspec表示[host][:port][,…]
dbname为数据库名称。注意:不允许使用初始化用户进行远程登录。
paramspec为name=value[&…]。
- 在DSN格式中,对于多IP的场景:
- 当num(ip) = num(port)时,ip和port是一一对应匹配。
- 当num(ip) > num(port)时,无法匹配到port的ip均与第一个port匹配。例如,host = ip1, ip2, ip3 port = port1, port2的匹配情况为ip1:port1, ip2:port2, ip3:port1。
- 当num(ip) < num(port)时,则多余的port被舍弃,即使用不到。例如host = ip1, ip2, ip3 port = port1, port2, port3, port4的匹配情况为ip1:port1, ip2:port2, ip3:port3。
- 在URL格式中,对于多IP的场景:
- URL串中ip:port必须成对出现,即num(ip) = num(port),并以逗号隔开。例如, opengauss://user:password@ip1:port1, ip2:port2, ip3:port3/postgres。
- URL串中仅包含多ip,port由环境变量指定或采用默认值5432。例如opengauss://user:password@ip1, ip2, ip3/postgres并设置环境变量PGPORT = "port1, port2",其匹配情况为ip1:port1, ip2:port2, ip3:port1。未设置环境变量的匹配情况为ip1:5432,ip2:5432,ip3:5432。
参数
示例一:
package main
//依赖包根据环境中依赖包路径设置。
import (
"context"
"database/sql"
"fmt"
_ "gitee.com/opengauss/openGauss-connector-go-pq"
"log"
"strings"
"time"
)
// 以下代码以多ip:port为例,本示例以用户名和密码保存在环境变量中为例,运行本示例前请先在本地环境中设置环境变量(环境变量名称请根据自身情况进行设置)。
func main() {
ctx := context.Background()
ctx2SecondTimeout, cancelFunc2SecondTimeout := context.WithTimeout(ctx, 2 * time.Second)
defer cancelFunc2SecondTimeout()
hostip1 := os.Getenv("GOHOSTIP1") //GOHOSTIP1为写入环境变量的IP地址。
hostip2 := os.Getenv("GOHOSTIP2") //GOHOSTIP2为写入环境变量的IP地址。
hostip3 := os.Getenv("GOHOSTIP3") //GOHOSTIP3为写入环境变量的IP地址。
port1 := os.Getenv("GOPORT1") //GOPORT1为写入环境变量的port。
port2 := os.Getenv("GOPORT2") //GOPORT2为写入环境变量的port。
usrname := os.Getenv("GOUSRNAME") //GOUSRNAME为写入环境变量的用户名。
passwd := os.Getenv("GOPASSWD") //GOPASSWDW为写入环境变量的用户密码。
str := "host="+hostip1+","+hostip2+","+hostip3+" port="+port1+","+port2+" user="+usrname+" password="+passwd+" dbname=postgres sslmode=disable" // DSN连接串。
//str := "opengauss://"+usrname+":"+passwd+"@"+hostip1+":"+port1+","+hostip2+":"+port2+","+hostip3+"/postgres?sslmode=disable" // URL连接串。
db, err:= sql.Open("opengauss", str)
if err != nil {
log.Fatal(err)
}
defer db.Close()
// Ping database connection with 2 second timeout
err = db.PingContext(ctx2SecondTimeout)
if err != nil {
log.Fatal(err)
}
sqls := []string {
"drop table if exists testExecContext",
"create table testExecContext(f1 int, f2 varchar(20), f3 number, f4 timestamptz, f5 boolean)",
"insert into testExecContext values(1, 'abcdefg', 123.3, '2022-02-08 10:30:43.31 +08', true)",
"insert into testExecContext values(:f1, :f2, :f3, :f4, :f5)",
}
inF1 := []int{2, 3, 4, 5, 6}
intF2 := []string{"hello world", "华为", "北京2022冬奥会", "nanjing", "研究所"}
intF3 := []float64{641.43, 431.54, 5423.52, 665537.63, 6503.1}
intF4 := []time.Time{
time.Date(2022, 2, 8, 10, 35, 43, 623431, time.Local),
time.Date(2022, 2, 10, 19, 11, 54, 353431, time.Local),
time.Date(2022, 2, 12, 6, 11, 15, 636431, time.Local),
time.Date(2022, 2, 14, 4, 51, 22, 747653, time.Local),
time.Date(2022, 2, 16, 13, 45, 55, 674636, time.Local),
}
intF5 := []bool{false, true, false, true, true}
for _, s := range sqls {
if strings.Contains(s, ":f") {
for i, _ := range inF1 {
_, err := db.ExecContext(ctx2SecondTimeout, s, inF1[i], intF2[i], intF3[i], intF4[i], intF5[i])
if err != nil {
log.Fatal(err)
}
}
} else {
_, err = db.ExecContext(ctx2SecondTimeout, s)
if err != nil {
log.Fatal(err)
}
}
}
var f1 int
var f2 string
var f3 float64
var f4 time.Time
var f5 bool
err = db.QueryRowContext(ctx2SecondTimeout, "select * from testExecContext").Scan(&f1, &f2, &f3, &f4, &f5)
if err != nil {
log.Fatal(err)
} else {
fmt.Printf("f1:%v, f2:%v, f3:%v, f4:%v, f5:%v\n", f1, f2, f3, f4, f5)
}
row, err :=db.QueryContext(ctx2SecondTimeout, "select * from testExecContext where f1 > :1", 1)
if err != nil {
log.Fatal(err)
}
defer row.Close()
for row.Next() {
err = row.Scan(&f1, &f2, &f3, &f4, &f5)
if err != nil {
log.Fatal(err)
} else {
fmt.Printf("f1:%v, f2:%v, f3:%v, f4:%v, f5:%v\n", f1, f2, f3, f4, f5)
}
}
}