Go言語で並行してデータベースを照会する方法
Go言語で並列にデータベースクエリを実現するには、goroutineとチャネルを使用できます。以下は簡単なサンプルコードです。
package main
import (
"database/sql"
"fmt"
"log"
"sync"
_ "github.com/go-sql-driver/mysql"
)
type Result struct {
ID int
Name string
}
func dbQuery(db *sql.DB, query string, resultChan chan<- Result, wg *sync.WaitGroup) {
defer wg.Done()
rows, err := db.Query(query)
if err != nil {
log.Printf("Error executing query: %s\n", err)
return
}
defer rows.Close()
for rows.Next() {
var result Result
err := rows.Scan(&result.ID, &result.Name)
if err != nil {
log.Printf("Error scanning result: %s\n", err)
return
}
resultChan <- result
}
}
func main() {
db, err := sql.Open("mysql", "user:password@tcp(localhost:3306)/database")
if err != nil {
log.Fatalf("Error connecting to database: %s\n", err)
}
defer db.Close()
queries := []string{"SELECT id, name FROM table1", "SELECT id, name FROM table2"}
resultChan := make(chan Result)
var wg sync.WaitGroup
for _, query := range queries {
wg.Add(1)
go dbQuery(db, query, resultChan, &wg)
}
go func() {
wg.Wait()
close(resultChan)
}()
for result := range resultChan {
fmt.Printf("ID: %d, Name: %s\n", result.ID, result.Name)
}
}
上記のコードでは、まずデータベース接続を確立し、SQLクエリ文と結果チャネルを受け取り、データベースからクエリ文でデータを抽出し、結果を結果チャネルに送信するQuery関数という関数を定義しています。
メイン関数で、クエリ文のスライスを定義し、結果用のチャネルとウェイトグループを作成します。次に、クエリ文スライスをループ処理し、各クエリ文に対してクエリを実行する goroutine を起動します。goroutine では、Query 関数を呼び出してデータベースクエリを実行し、結果を結果チャネルに送信します。
最後に、メイン関数で全てのクエリ操作が完了するまで待機する Goroutine を起動し、全ての結果が処理されたら結果チャネルを閉じます。その後、結果チャネルを反復処理し、クエリ結果を出力します。
これにより、並列にデータベースに対するクエリを実行する機能を実現しました。