
# 通过Go连接GeminiDB Cassandra
本节主要介绍使用Go语言连接GeminiDB Cassandra的基本读写操作。
#### 前提条件
- 已成功创建GeminiDB Cassandra实例，且实例状态正常。创建GeminiDB Cassandra实例的方法请参见[购买GeminiDB Cassandra实例](https://support.huaweicloud.com/cassandraug-nosql/nosql_02_0002.html)。
- 已创建弹性云服务器，创建弹性云服务器的方法，请参见《弹性云服务器》中"[创建弹性云服务器](https://support.huaweicloud.com/usermanual-ecs/ecs_03_7002.html)"章节。
- 弹性云服务器上已经安装Go环境，若未安装，请下载[Go安装包](https://go.dev/)。
 
#### 操作步骤
1. 获取GeminiDB Cassandra实例的内网IP地址、端口。 
   内网IP地址和端口的获取方法请参见[GeminiDB Cassandra查看IP地址和端口](https://support.huaweicloud.com/cassandraug-nosql/nosql_02_0201.html)。
   
   
2. 登录弹性云服务器，具体操作请参见《弹性云服务器》中"[登录弹性云服务器](https://support.huaweicloud.com/ecs_faq/ecs_faq_0632.html)"。
3. 编辑连接GeminiDB Cassandra实例的代码。 
   ```
   import (
       "os"
   )
   // Default LoadBalancingPolicy RoundRobinHostPolicy
   cluster := gocql.NewCluster("192.168.1.1", "192.168.1.2", "192.168.1.3")
   // 认证用的用户名和密码直接写到代码中有很大的安全风险，建议在配置文件或者环境变量中存放(密码应密文存放、使用时解密)，确保安全；
   // 本示例以用户名和密码保存在环境变量中为例，运行本示例前请先在本地环境中设置环境变量(环境变量名称请根据自身情况进行设置)EXAMPLE_USERNAME_ENV和EXAMPLE_PASSWORD_ENV。
   username = os.Getenv("EXAMPLE_USERNAME_ENV"),
   password = os.Getenv("EXAMPLE_PASSWORD_ENV"),
   cluster.Authenticator = gocql.PasswordAuthenticator{
   Username: username,
   Password: password
    }
   cluster.Keyspace = "ks1"
   // connect to the cluster
   session, err := cluster.CreateSession()
   if err != nil {
       log.Fatal(err)
   }
   defer session.Close()
   ```
   
   
4. 运行示例代码，确认结果是否正常。
 
#### 执行读写
使用 Session.Query 创建查询。查询参数不能用于其他语句，并且不能在开始查询之后进行修改。
要在不读取结果的情况下执行查询，请使用 Query.Exec：
```
err := session.Query(`INSERT INTO tweet (timeline, id, text) VALUES (?, ?, ?)`,
        "me", gocql.TimeUUID(), "hello world").WithContext(ctx).Exec()
```
可以通过调用 Query.Scan 读取单行：
```
err := session.Query(`SELECT id, text FROM tweet WHERE timeline = ? LIMIT 1`,
        "me").WithContext(ctx).Consistency(gocql.One).Scan(&id, &text)
```
可以使用 Iter.Scanner 读取多行：
```
scanner := session.Query(`SELECT id, text FROM tweet WHERE timeline = ?`,
    "me").WithContext(ctx).Iter().Scanner()
 for scanner.Next() {
    var (
        id gocql.UUID
        text string
    )
    err = scanner.Scan(&id, &text)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("Tweet:", id, text)
 }
 // scanner.Err() closes the iterator, so scanner nor iter should be used afterwards.
 if err := scanner.Err(); err != nil {
    log.Fatal(err)
 }
```
#### 同时执行多个查询
从多个Goroutine中使用Session是安全的，因此要执行多个并发查询，只需从多个Worker Goroutine中执行它们即可。
```
results := make(chan error, 2)
go func() {
    results <- session.Query(`INSERT INTO tweet (timeline, id, text) VALUES (?, ?, ?)`,
        "me", gocql.TimeUUID(), "hello world 1").Exec()
}()
go func() {
    results <- session.Query(`INSERT INTO tweet (timeline, id, text) VALUES (?, ?, ?)`,
        "me", gocql.TimeUUID(), "hello world 2").Exec()
}()
```
