Go でのデータベース インタラクション: SQL から NoSQL へ

Susan Sarandon
リリース: 2024-10-01 22:07:02
オリジナル
968 人が閲覧しました

Database Interactions in Go: From SQL to NoSQL

導入

Go (Golang) は、堅牢で高性能のバックエンド サービスを構築するための一般的な選択肢となっています。 Go の主な強みの 1 つは、従来の SQL データベースを使用しているか最新の NoSQL ソリューションを使用しているかにかかわらず、データベース操作に対する優れたサポートです。このガイドでは、SQL と NoSQL の両方のアプローチをカバーしながら、Go でデータベースを操作する方法を説明します。

目次

  1. SQL データベースの相互作用
    • database/sql パッケージの使用
    • ORM の使用: GORM
  2. NoSQL データベースの相互作用
    • MongoDB と公式 Go ドライバー
  3. ベスト プラクティスと一般的な落とし穴
  4. 結論

SQL データベースの相互作用

データベース/sql パッケージの使用

Go の標準ライブラリは、SQL (または SQL に似た) データベースに関する汎用インターフェイスを提供する、database/sql パッケージを提供します。このパッケージは、データベース固有のドライバーと組み合わせて使用​​するように設計されています。

SQLite を使用した簡単な例から始めましょう:

package main

import (
    "database/sql"
    "fmt"
    "log"
)

func main() {
    // Open the database
    db, err := sql.Open("sqlite3", "./test.db")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    // Create table
    _, err = db.Exec(`CREATE TABLE IF NOT EXISTS users (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT,
        age INTEGER
    )`)
    if err != nil {
        log.Fatal(err)
    }

    // Insert a user
    result, err := db.Exec("INSERT INTO users (name, age) VALUES (?, ?)", "Alice", 30)
    if err != nil {
        log.Fatal(err)
    }

    // Get the ID of the inserted user
    id, err := result.LastInsertId()
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Inserted user with ID: %d\n", id)

    // Query for the user
    var name string
    var age int
    err = db.QueryRow("SELECT name, age FROM users WHERE id = ?", id).Scan(&name, &age)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("User: %s, Age: %d\n", name, age)
}
ログイン後にコピー

この例では、Go での SQL データベースの操作の基本を示します。

  1. データベース接続を開く
  2. テーブルの作成
  3. データを挿入しています
  4. データのクエリ

database/sql パッケージはデータベースへの低レベルのインターフェイスを提供し、クエリと操作を細かく制御できます。

ORM の操作: GORM

database/sql パッケージは強力ですが、多くの開発者は、より便利なデータベース操作のためにオブジェクト リレーショナル マッピング (ORM) ツールの使用を好みます。 GORM は Go で最も人気のある ORM の 1 つです。

SQLite で GORM を使用する例を次に示します:

package main

import (
    "fmt"
    "log"

    "gorm.io/driver/sqlite"
    "gorm.io/gorm"
)

type User struct {
    ID   uint
    Name string
    Age  int
}

func main() {
    // Open the database
    db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
    if err != nil {
        log.Fatal(err)
    }

    // Auto Migrate the schema
    db.AutoMigrate(&User{})

    // Create a user
    user := User{Name: "Bob", Age: 25}
    result := db.Create(&user)
    if result.Error != nil {
        log.Fatal(result.Error)
    }
    fmt.Printf("Inserted user with ID: %d\n", user.ID)

    // Query for the user
    var fetchedUser User
    db.First(&fetchedUser, user.ID)
    fmt.Printf("User: %s, Age: %d\n", fetchedUser.Name, fetchedUser.Age)

    // Update the user
    db.Model(&fetchedUser).Update("Age", 26)

    // Delete the user
    db.Delete(&fetchedUser)
}
ログイン後にコピー

GORM はデータベース操作に対するより高いレベルの抽象化を提供し、生の SQL クエリを記述する代わりに Go 構造体を直接操作できるようにします。また、自動移行、フック、関連付けなどの機能も提供します。

NoSQL データベースの相互作用

公式 Go ドライバーを使用した MongoDB

NoSQL データベースの場合、公式 Go ドライバーを使用して MongoDB と対話する方法を見てみましょう。

package main

import (
    "context"
    "fmt"
    "log"
    "time"

    "go.mongodb.org/mongo-driver/bson"
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
)

type User struct {
    Name string `bson:"name"`
    Age  int    `bson:"age"`
}

func main() {
    // Set client options
    clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")

    // Connect to MongoDB
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()
    client, err := mongo.Connect(ctx, clientOptions)
    if err != nil {
        log.Fatal(err)
    }

    // Check the connection
    err = client.Ping(context.TODO(), nil)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println("Connected to MongoDB!")

    // Get a handle for your collection
    collection := client.Database("test").Collection("users")

    // Insert a user
    user := User{Name: "Charlie", Age: 35}
    insertResult, err := collection.InsertOne(context.TODO(), user)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Inserted user with ID: %v\n", insertResult.InsertedID)

    // Find a user
    var result User
    filter := bson.M{"name": "Charlie"}
    err = collection.FindOne(context.TODO(), filter).Decode(&result)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Found user: %+v\n", result)

    // Update a user
    update := bson.M{
        "$set": bson.M{
            "age": 36,
        },
    }
    updateResult, err := collection.UpdateOne(context.TODO(), filter, update)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Updated %v user(s)\n", updateResult.ModifiedCount)

    // Delete a user
    deleteResult, err := collection.DeleteOne(context.TODO(), filter)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Deleted %v user(s)\n", deleteResult.DeletedCount)

    // Disconnect
    err = client.Disconnect(context.TODO())
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("Connection to MongoDB closed.")
}
ログイン後にコピー

この例では、公式 Go ドライバーを使用した MongoDB での基本的な CRUD (作成、読み取り、更新、削除) 操作を示します。

ベストプラクティスとよくある落とし穴

Go でデータベースを操作する場合は、次のベスト プラクティスに留意してください。

  1. 接続プーリングを使用する: データベース/SQL ドライバーとほとんどの NoSQL ドライバーの両方が接続プーリングを実装します。操作ごとに新しいデータベース接続を開くのではなく、必ずデータベース接続を再利用してください。

  2. エラーを適切に処理する: データベース操作によって返されたエラーを常に確認し、適切に処理します。

  3. プリペアド ステートメントを使用する: SQL データベースの場合、プリペアド ステートメントを使用してパフォーマンスを向上させ、SQL インジェクション攻撃を防ぎます。

  4. リソースを閉じる: 結果セット、ステートメント、データベース接続を使い終わったら、必ず閉じてください。これには defer キーワードが役立ちます。

  5. 必要に応じてトランザクションを使用する: 複数の手順が必要な操作の場合は、トランザクションを使用してデータの一貫性を確保します。

  6. N 1 クエリの問題に注意してください: ORM を使用するときは、N 1 クエリの問題に注意し、必要に応じて積極的な読み込みを使用してください。

  7. タイムアウトにコンテキストを使用する: コンテキストを使用して、データベース操作、特に長時間実行クエリのタイムアウトを設定します。

避けるべき一般的な落とし穴:

  1. SQL インジェクションの脆弱性を無視する: 常にパラメーター化されたクエリまたはプリペアド ステートメントを使用します。
  2. 接続エラーを処理しない: 接続エラーをチェックして処理し、必要に応じて再試行ロジックを実装します。
  3. GORM フックの使いすぎ: GORM フックを使いすぎると便利ですが、デバッグが難しい問題が発生する可能性があります。
  4. インデックスが適切に作成されていません: データベース スキーマがクエリ パターンに対して適切にインデックス付けされていることを確認してください。
  5. 機密データを平文で保存する: 機密データはデータベースに保存する前に必ず暗号化してください。

結論

Go は、SQL と NoSQL の両方のデータベース対話に対する強力なサポートを提供します。データベース/SQL の低レベル制御を好む場合でも、GORM などの ORM の利便性を好む場合でも、MongoDB などの NoSQL データベースでの作業を好む場合でも、Go はそれを実現します。

以上がGo でのデータベース インタラクション: SQL から NoSQL への詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート