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 を起動し、全ての結果が処理されたら結果チャネルを閉じます。その後、結果チャネルを反復処理し、クエリ結果を出力します。

これにより、並列にデータベースに対するクエリを実行する機能を実現しました。

bannerAds