更新时间:2026-07-28 GMT+08:00
分享

典型应用开发示例

本章节的示例演示连接数据库、建表、插入数据并返回结果的常规操作。示例一以单ip:port为例,示例二以多ip:port为例。

示例一

package main
//依赖包根据环境中依赖包路径设置。
import (
   "database/sql"
   "fmt"
   "os"
   _ [go驱动模块名] //请根据go驱动实际模块名替换。
   "log"
   "strings"
   "time"
)

// 以下代码以单ip:port为例,本示例以IP地址、端口号、用户名、密码保存在环境变量中为例,运行本示例前请先在本地环境中设置环境变量(环境变量名称请根据自身情况进行设置)。
func main() {
   hostip := os.Getenv("GOHOSTIP")   //GOHOSTIP为写入环境变量的IP地址。
   port := os.Getenv("GOPORT")       //GOPORT为写入环境变量的端口号。
   usrname := os.Getenv("GOUSRNAME") //GOUSRNAME为写入环境变量的用户名。
   passwd := os.Getenv("GOPASSWD")   //GOPASSWD为写入环境变量的密码。
   str := "host=" + hostip + " port=" + port + " user=" + usrname + " password=" + passwd + " dbname=gaussdb sslmode=disable" //DSN连接串。用户需要自行设置dbname和sslmode关键字的取值。
   //str := "gaussdb://" + usrname + ":" + passwd + "@" + hostip + ":" + port + "/gaussdb?sslmode=disable"  //URL连接串。用户需要自行设置数据库名称和sslmode的取值。
   db, err := sql.Open("gaussdb", str)
   if err != nil {
      log.Fatal(err)  //执行出错时,使用标准库log的Fatal方法输出错误信息,并同时调用os.Exit(1)终止程序。
   }
   defer db.Close()  //延迟执行db.Close(),确保在数据库操作完毕后关闭连接。
   err = db.Ping()  //验证是否成功连接数据库。
   if err != nil {
      log.Fatal(err)  
   }

   //定义包含4个SQL语句的字符串切片。   
   sqls := []string{
      "DROP TABLE IF EXISTS testExec",  //若testExec表存在则删除。
      "CREATE TABLE testExec(f1 int, f2 varchar(20), f3 number, f4 timestamptz, f5 boolean)",  //创建testExec表。
      "INSERT INTO testExec VALUES(1, 'abcdefg', 123.3, '2022-02-08 10:30:43.31 +08', true)",  //插入一条数据。
      "INSERT INTO testExec VALUES(:f1, :f2, :f3, :f4, :f5)",  //参数化插入语句。
   }

   //数据切片定义。   
   intF1 := []int{2, 3, 4, 5, 6}  
   intF2 := []string{"hello world", "华为", "北京", "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}

   //循环结构,使用range关键字遍历sqls切片。
   for _, s := range sqls {
      if strings.Contains(s, ":f") {  //判断是否参数化SQL。
         for i, _ := range intF1 {  //遍历数据索引。
            _, err := db.Exec(s, intF1[i], intF2[i], intF3[i], intF4[i], intF5[i])   //执行参数化插入。
            if err != nil {
               log.Fatal(err)
            }
         }
      } else {  // 非参数化SQL。
         _, err = db.Exec(s)  //直接执行DDL。
         if err != nil {
            log.Fatal(err)
         }
      }
   }

   var f1 int
   var f2 string
   var f3 float64
   var f4 time.Time
   var f5 bool
   row := db.QueryRow("SELECT * FROM testExec")  //查询单行数据。  
   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)
   }

   rows, err := db.Query("SELECT * FROM testExec WHERE f1 > :1", 1)  //执行带条件的查询。
   if err != nil {
      log.Fatal(err)
   } 
   defer rows.Close()  //使用defer确保rows在函数结束时被关闭。
   //使用for循环和type Rows接口的Next和Scan方法逐行将数据扫描到指定的变量。
   for rows.Next() {
      err = rows.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)
      }
   }
}

示例运行结果如下:

f1:1, f2:abcdefg, f3:123.3, f4:2022-02-08 10:30:43.31 +0800 CST, f5:true
f1:2, f2:hello world, f3:641.43, f4:2022-02-08 10:35:43.000623 +0800 CST, f5:false
f1:3, f2:华为, f3:431.54, f4:2022-02-10 19:11:54.000353 +0800 CST, f5:true
f1:4, f2:北京, f3:5423.52, f4:2022-02-12 06:11:15.000636 +0800 CST, f5:false
f1:5, f2:nanjing, f3:665537.63, f4:2022-02-14 04:51:22.000748 +0800 CST, f5:true
f1:6, f2:研究所, f3:6503.1, f4:2022-02-16 13:45:55.000675 +0800 CST, f5:true

示例二

package main
//依赖包根据环境中依赖包路径设置。
import (
 "context"
 "database/sql"
 "fmt"
 "os"
 _ [go驱动模块名] //请根据go驱动实际模块名替换。
 "log"
 "strings"
 "time"
)
// 以下代码以多ip:port为例,本示例以IP地址、端口号、用户名、密码保存在环境变量中为例,运行本示例前请先在本地环境中设置环境变量(环境变量名称请根据自身情况进行设置)。
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为写入环境变量的端口号。
  port2 := os.Getenv("GOPORT2")       //GOPORT2为写入环境变量的端口号。
  usrname := os.Getenv("GOUSRNAME") //GOUSRNAME为写入环境变量的用户名。
  passwd := os.Getenv("GOPASSWD")   //GOPASSWD为写入环境变量的密码。

  str := "host="+hostip1+","+hostip2+","+hostip3+" port="+port1+","+port2+" user="+usrname+" password="+passwd+" dbname=gaussdb sslmode=disable" //DSN连接串。用户需要自行设置dbname和sslmode关键字的取值。
  //str := "gaussdb://"+usrname+":"+passwd+"@"+hostip1+":"+port1+","+hostip2+":"+port2+","+hostip3+"/gaussdb?sslmode=disable"  //URL连接串。用户需要自行设置数据库名称和sslmode的取值。
 db, err := sql.Open("gaussdb", str)
 if err != nil {
  log.Fatal(err)
 }
 defer db.Close()  //延迟执行db.Close(),确保在数据库操作完毕后关闭连接。

 // Ping database connection with 2 second timeout
 err = db.PingContext(ctx2SecondTimeout)  //验证是否成功连接数据库。
 if err != nil {
  log.Fatal(err)
 }

 //定义包含4个SQL语句的字符串切片。
 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)",  //参数化插入语句。
	}

        //数据切片定义。
	intF1 := []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}

        //循环结构,使用range关键字遍历sqls切片。
	for _, s := range sqls {
		if strings.Contains(s, ":f") {  //判断是否参数化SQL。
			for i, _ := range intF1 {  //遍历数据索引。
				_, err := db.ExecContext(ctx2SecondTimeout, s, intF1[i], intF2[i], intF3[i], intF4[i], intF5[i])   //执行参数化插入。
				if err != nil {
					log.Fatal(err)
				}
			}
		} else {  // 非参数化SQL。
			_, err = db.ExecContext(ctx2SecondTimeout, s)  //直接执行DDL。
			if err != nil {
				log.Fatal(err)
			}
		}
	}

	var f1 int
	var f2 string
	var f3 float64
	var f4 time.Time
	var f5 bool
	row := db.QueryRowContext(ctx2SecondTimeout, "SELECT * FROM testExecContext")  //查询单行数据。
        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)
	}

	rows, err := db.QueryContext(ctx2SecondTimeout, "SELECT * FROM testExecContext WHERE f1 > :1", 1)
	if err != nil {
		log.Fatal(err)
	}
	defer rows.Close()  //使用defer确保rows在函数结束时被关闭。   
     
       //使用for循环和type Rows接口的Next和Scan方法逐行将数据扫描到指定的变量。
	for rows.Next() {
		err = rows.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)
		}
	}
}

示例运行结果如下:

f1:1, f2:abcdefg, f3:123.3, f4:2022-02-08 10:30:43.31 +0800 CST, f5:true
f1:2, f2:hello world, f3:641.43, f4:2022-02-08 10:35:43.000623 +0800 CST, f5:false
f1:3, f2:华为, f3:431.54, f4:2022-02-10 19:11:54.000353 +0800 CST, f5:true
f1:4, f2:北京2022冬奥会, f3:5423.52, f4:2022-02-12 06:11:15.000636 +0800 CST, f5:false
f1:5, f2:nanjing, f3:665537.63, f4:2022-02-14 04:51:22.000748 +0800 CST, f5:true
f1:6, f2:研究所, f3:6503.1, f4:2022-02-16 13:45:55.000675 +0800 CST, f5:true

相关文档