本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
適用於 Go 的 Amazon QLDB 驅動程序-快速入門
重要
支援結束通知:現有客戶將能夠使用 Amazon,QLDB直到 2025 年 7 月 31 日終止支援為止。有關更多詳細信息,請參閱將 Amazon QLDB 分類帳遷移到 Amazon Aurora 郵政. SQL
在本教學中,您將學習如何使用最新版本的適用於 Go 的 Amazon QLDB 驅動程式來設定簡單的應用程式。本指南包含安裝驅動程式的步驟,以及基本建立、讀取、更新和刪除 (CRUD) 操作的簡短程式碼範例。
主題
必要條件
在開始之前,請確保您執行以下操作:
-
如果您尚未完成 Go 驅動程序,請完成此操作。必要條件這包括註冊 AWS,授予用於開發的程序化訪問權限以及安裝 Go。
-
建立名為的分類帳
quick-start
。若要瞭解如何建立分類帳,請參閱Amazon QLDB 分類帳的基本操作或步驟 1:建立新分類帳在「開始使用主控台」中的。
步驟 1:安裝驅動程式
確保您的項目正在使用 Go 模塊
在您的項目目錄中,輸入以下go get
命令。
$
go get -u github.com/awslabs/amazon-qldb-driver-go/v3/qldbdriver
安裝驅動程式也會安裝其相依性,包括 AWS SDK for Go v2
步驟 2:匯入套件
匯入下列 AWS 套件。
import ( "context" "fmt" "github.com/amzn/ion-go/ion" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/qldbSession" "github.com/awslabs/amazon-qldb-driver-go/v3/qldbdriver" )
步驟 3:初始化驅動程式
初始化連線至名為之分類帳之驅動程式的執行個體quick-start
。
cfg, err := config.LoadDefaultConfig(context.TODO()) if err != nil { panic(err) } qldbSession := qldbsession.NewFromConfig(cfg, func(options *qldbsession.Options) { options.Region = "
us-east-1
" }) driver, err := qldbdriver.New( "quick-start", qldbSession, func(options *qldbdriver.DriverOptions) { options.LoggerVerbosity = qldbdriver.LogInfo }) if err != nil { panic(err) } defer driver.Shutdown(context.Background())
注意
在此代碼示例中,替換 us-east-1
與您創建分類帳的 AWS 區域
位置。
第 4 步:創建一個表和索引
下列程式碼範例會示範如何執行CREATE TABLE
和CREATE
INDEX
陳述式。
_, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { _, err := txn.Execute("CREATE TABLE People") if err != nil { return nil, err } // When working with QLDB, it's recommended to create an index on fields we're filtering on. // This reduces the chance of OCC conflict exceptions with large datasets. _, err = txn.Execute("CREATE INDEX ON People (firstName)") if err != nil { return nil, err } _, err = txn.Execute("CREATE INDEX ON People (age)") if err != nil { return nil, err } return nil, nil }) if err != nil { panic(err) }
此程式碼會建立名為的資料表People
,以及該資料表上firstName
和age
欄位的索引。需要索引來優化查詢性能並有助於限制樂觀的並發控制(OCC)衝突異常。
步驟 5:插入文件
下列程式碼範例會示範如何執行INSERT
陳述式。QLDB支援 P artiQL 查詢語言 (SQL相容) 和 Amazon 離子資料格式 (的JSON超集)。
使用 PartiQL
下列程式碼會使用字串常值 PartiQL 陳述式,將文件插入People
資料表中。
_, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { return txn.Execute("INSERT INTO People {'firstName': 'Jane', 'lastName': 'Doe', 'age': 77}") }) if err != nil { panic(err) }
使用離子數據類型
與 Go 的內置JSON軟件包
-
假設您已命名為以下 Go 結構
Person
。type Person struct { FirstName string `ion:"firstName"` LastName string `ion:"lastName"` Age int `ion:"age"` }
-
建立
Person
的執行個體。person := Person{"John", "Doe", 54}
驅動程式會為您封送離子編碼的
person
文字表示。重要
為了使元帥和解組正常工作,必須導出 Go 數據結構的字段名稱(首字母大寫)。
-
將
person
執行個體傳遞給交易的Execute
方法。_, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { return txn.Execute("INSERT INTO People ?", person) }) if err != nil { panic(err) }
此範例使用問號 (
?
) 做為變數預留位置,將文件資訊傳遞至陳述式。使用預留位置時,您必須傳遞離子編碼的文字值。
步驟 6:查詢文件
下列程式碼範例會示範如何執行SELECT
陳述式。
p, err := driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { result, err := txn.Execute("SELECT firstName, lastName, age FROM People WHERE age = 54") if err != nil { return nil, err } // Assume the result is not empty hasNext := result.Next(txn) if !hasNext && result.Err() != nil { return nil, result.Err() } ionBinary := result.GetCurrentData() temp := new(Person) err = ion.Unmarshal(ionBinary, temp) if err != nil { return nil, err } return *temp, nil }) if err != nil { panic(err) } var returnedPerson Person returnedPerson = p.(Person) if returnedPerson != person { fmt.Print("Queried result does not match inserted struct") }
這個範例會從People
資料表查詢您的文件,假設結果集不是空的,並從結果傳回您的文件。
步驟 7:更新文件
下列程式碼範例會示範如何執行UPDATE
陳述式。
person.Age += 10 _, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { return txn.Execute("UPDATE People SET age = ? WHERE firstName = ?", person.Age, person.FirstName) }) if err != nil { panic(err) }
步驟 8:查詢更新的文件
下列程式碼範例會依據查詢People
資料表,firstName
並傳回結果集中的所有文件。
p, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { result, err := txn.Execute("SELECT firstName, lastName, age FROM People WHERE firstName = ?", person.FirstName) if err != nil { return nil, err } var people []Person for result.Next(txn) { ionBinary := result.GetCurrentData() temp := new(Person) err = ion.Unmarshal(ionBinary, temp) if err != nil { return nil, err } people = append(people, *temp) } if result.Err() != nil { return nil, result.Err() } return people, nil }) if err != nil { panic(err) } var people []Person people = p.([]Person) updatedPerson := Person{"John", "Doe", 64} if people[0] != updatedPerson { fmt.Print("Queried result does not match updated struct") }
步驟 9:放下表格
下列程式碼範例會示範如何執行DROP TABLE
陳述式。
_, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { return txn.Execute("DROP TABLE People") }) if err != nil { panic(err) }
執行完整的應用程式
下列程式碼範例是應用程式的完整版本。您也可以從頭到尾複製並執行此程式碼範例,而不是個別執行前述步驟。此應用程序演示了名為的分類帳上的一些基本CRUD操作quick-start
。
注意
在執行此程式碼之前,請確定您尚未在quick-start
分類帳People
中命名為使用中的資料表。
package main import ( "context" "fmt" "github.com/amzn/ion-go/ion" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/qldbsession" "github.com/awslabs/amazon-qldb-driver-go/v2/qldbdriver" ) func main() { awsSession := session.Must(session.NewSession(aws.NewConfig().WithRegion("
us-east-1
"))) qldbSession := qldbsession.New(awsSession) driver, err := qldbdriver.New( "quick-start", qldbSession, func(options *qldbdriver.DriverOptions) { options.LoggerVerbosity = qldbdriver.LogInfo }) if err != nil { panic(err) } defer driver.Shutdown(context.Background()) _, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { _, err := txn.Execute("CREATE TABLE People") if err != nil { return nil, err } // When working with QLDB, it's recommended to create an index on fields we're filtering on. // This reduces the chance of OCC conflict exceptions with large datasets. _, err = txn.Execute("CREATE INDEX ON People (firstName)") if err != nil { return nil, err } _, err = txn.Execute("CREATE INDEX ON People (age)") if err != nil { return nil, err } return nil, nil }) if err != nil { panic(err) } _, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { return txn.Execute("INSERT INTO People {'firstName': 'Jane', 'lastName': 'Doe', 'age': 77}") }) if err != nil { panic(err) } type Person struct { FirstName string `ion:"firstName"` LastName string `ion:"lastName"` Age int `ion:"age"` } person := Person{"John", "Doe", 54} _, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { return txn.Execute("INSERT INTO People ?", person) }) if err != nil { panic(err) } p, err := driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { result, err := txn.Execute("SELECT firstName, lastName, age FROM People WHERE age = 54") if err != nil { return nil, err } // Assume the result is not empty hasNext := result.Next(txn) if !hasNext && result.Err() != nil { return nil, result.Err() } ionBinary := result.GetCurrentData() temp := new(Person) err = ion.Unmarshal(ionBinary, temp) if err != nil { return nil, err } return *temp, nil }) if err != nil { panic(err) } var returnedPerson Person returnedPerson = p.(Person) if returnedPerson != person { fmt.Print("Queried result does not match inserted struct") } person.Age += 10 _, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { return txn.Execute("UPDATE People SET age = ? WHERE firstName = ?", person.Age, person.FirstName) }) if err != nil { panic(err) } p, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { result, err := txn.Execute("SELECT firstName, lastName, age FROM People WHERE firstName = ?", person.FirstName) if err != nil { return nil, err } var people []Person for result.Next(txn) { ionBinary := result.GetCurrentData() temp := new(Person) err = ion.Unmarshal(ionBinary, temp) if err != nil { return nil, err } people = append(people, *temp) } if result.Err() != nil { return nil, result.Err() } return people, nil }) if err != nil { panic(err) } var people []Person people = p.([]Person) updatedPerson := Person{"John", "Doe", 64} if people[0] != updatedPerson { fmt.Print("Queried result does not match updated struct") } _, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { return txn.Execute("DROP TABLE People") }) if err != nil { panic(err) } }