Golang - MySQL データベースにアクセスする

Go 自体は、database/sqlインターフェイス層に相当するデータベース アクセス層を抽象化するためにこのパッケージを提供します。ただし、特定のデータベースにアクセスするには、そのデータベースに対応するドライバーをインストールする必要があります。MySQL の場合は、次のコマンドを実行してドライバーをインストールします。

go get -u github.com/go-sql-driver/mysql

ドライバーを使用すると、後でデータベースにアクセスするのが非常に簡単になります。

mysqlに接続する

接続パラメータを設定することによりsql.open、この関数は実際にデータベースにアクセスしません。

db, err := sql.Open("mysql", "username:password@(127.0.0.1:3306)/dbname?parseTime=true")

db.pingを通じてデータベースにアクセスし、接続が正常かどうかを確認します。接続パラメータが間違っている場合は、変数 err が割り当てられます

err := db.Ping()

MySQL にアクセスして CURD 操作を実行する

1 テーブルの作成

ユーザー テーブルを作成し、そのテーブル作成ステートメントが次のようになっているとします。

CREATE TABLE users (
    id INT AUTO_INCREMENT,
    username TEXT NOT NULL,
    password TEXT NOT NULL,
    created_at DATETIME,
    PRIMARY KEY (id)
);

go でテーブルを作成する操作は次のようになります。 err を使用してテーブルの作成に問題があるかどうかを判断できます。

query := `
    CREATE TABLE users (
        id INT AUTO_INCREMENT,
        username TEXT NOT NULL,
        password TEXT NOT NULL,
        created_at DATETIME,
        PRIMARY KEY (id)
    );`

// Executes the SQL query in our database. Check err to ensure there was no error.
_, err := db.Exec(query)

2 挿入データ

日付データを挿入する必要がある場合は、timeこのパッケージを導入する必要があります

import "time"

username := "johndoe"
password := "secret"
createdAt := time.Now()

// Inserts our data into the users table and returns with the result and a possible error.
// The result contains information about the last inserted id (which was auto-generated for us) and the count of rows this query affected.
result, err := db.Exec(`INSERT INTO users (username, password, created_at) VALUES (?, ?, ?)`, username, password, createdAt)

この変数はresult、挿入時のデータベースの変更情報 (挿入されたデータ行の ID や影響を受ける行の数など) を返すことができます。

userID, err := result.LastInsertId()

3 クエリデータ

3.1 単一データのクエリ

この簡潔な記述方法ではdb.QueryRow、単一データのクエリを有効にし、一連の変数をカプセル化することで、各変数を宣言するvar()必要がなくなります。var

var (
    id        int
    username  string
    password  string
    createdAt time.Time
)

// Query the database and scan the values into out variables. Don't forget to check for errors.
query := `SELECT id, username, password, created_at FROM users WHERE id = ?`
err := db.QueryRow(query, 1).Scan(&id, &username, &password, &createdAt)

3.2 複数のデータのクエリ

複数のデータのクエリは単一のデータとよく似ていますが、db.Queryここでは関数が呼び出され、複数のレコードを返すことができる点が異なりますが、db.QueryRow最大でも 1 つのレコードしか返されません。

複数のデータのクエリ結果については、Go フィールドとデータベース フィールド間の 1 対 1 マッピングを実現する構造を定義し、各行レコードを繰り返しスキャンして構造メンバーにカプセル化する必要があります。

type user struct {
    
    
    id        int
    username  string
    password  string
    createdAt time.Time
}

rows, err := db.Query(`SELECT id, username, password, created_at FROM users`) // check err
defer rows.Close()

var users []user
for rows.Next() {
    
    
    var u user
    err := rows.Scan(&u.id, &u.username, &u.password, &u.createdAt) // check err
    users = append(users, u)
}
err := rows.Err()

データベースにデータがある場合、ユーザーの構造体配列は次のようになります。

users {
    
    
    user {
    
    
        id:        1,
        username:  "johndoe",
        password:  "secret",
        createdAt: time.Time{
    
    wall: 0x0, ext: 63701044325, loc: (*time.Location)(nil)},
    },
    user {
    
    
        id:        2,
        username:  "alice",
        password:  "bob",
        createdAt: time.Time{
    
    wall: 0x0, ext: 63701044622, loc: (*time.Location)(nil)},
    },
}

4 データを削除する

実行するとdb.Exec削除操作を実現できます

_, err := db.Exec(`DELETE FROM users WHERE id = ?`, 1) // check err

完全なコード

package main

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

	_ "github.com/go-sql-driver/mysql"
)

func main() {
    
    
	db, err := sql.Open("mysql", "root:mysql520@(127.0.0.1:3306)/demo?parseTime=true")
	if err != nil {
    
    
		log.Fatal(err)
	}
	if err := db.Ping(); err != nil {
    
    
		log.Fatal(err)
	}

	{
    
     // Create a new table
		query := `
            CREATE TABLE users (
                id INT AUTO_INCREMENT,
                username TEXT NOT NULL,
                password TEXT NOT NULL,
                created_at DATETIME,
                PRIMARY KEY (id)
            );`

		if _, err := db.Exec(query); err != nil {
    
    
			log.Fatal(err)
		}
	}

	{
    
     // Insert a new user
		username := "johndoe"
		password := "secret"
		createdAt := time.Now()

		result, err := db.Exec(`INSERT INTO users (username, password, created_at) VALUES (?, ?, ?)`, username, password, createdAt)
		if err != nil {
    
    
			log.Fatal(err)
		}

		id, err := result.LastInsertId()
		fmt.Println(id)
	}

	{
    
     // Query a single user
		var (
			id        int
			username  string
			password  string
			createdAt time.Time
		)

		query := "SELECT id, username, password, created_at FROM users WHERE id = ?"
		if err := db.QueryRow(query, 1).Scan(&id, &username, &password, &createdAt); err != nil {
    
    
			log.Fatal(err)
		}

		fmt.Println(id, username, password, createdAt)
	}

	{
    
     // Query all users
		type user struct {
    
    
			id        int
			username  string
			password  string
			createdAt time.Time
		}

		rows, err := db.Query(`SELECT id, username, password, created_at FROM users`)
		if err != nil {
    
    
			log.Fatal(err)
		}
		defer rows.Close()

		var users []user
		for rows.Next() {
    
    
			var u user

			err := rows.Scan(&u.id, &u.username, &u.password, &u.createdAt)
			if err != nil {
    
    
				log.Fatal(err)
			}
			users = append(users, u)
		}
		if err := rows.Err(); err != nil {
    
    
			log.Fatal(err)
		}

		fmt.Printf("%#v", users)
	}

	{
    
    
		_, err := db.Exec(`DELETE FROM users WHERE id = ?`, 1)
		if err != nil {
    
    
			log.Fatal(err)
		}
	}
}

おすすめ

転載: blog.csdn.net/mryang125/article/details/114047458