Skip to content

GoアプリからPostgreSQLに接続する

cf. https://github.com/lib/pq

設定

  • ドライバをインストールします:
shell
go get github.com/lib/pq

実装

  • あらかじめeadbおよびユーザeadbuserを用意します。テーブル定義は下記とします:
sql
CREATE TABLE eadb.users (
    id INT PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY
    , name VARCHAR(10)
    , age INT
);
  • 下記でアプリを実装します:
go
package main

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

	"github.com/lib/pq"
)

func main() {
	// DB接続
	db, err := connectDB()
	if err != nil {
		fmt.Println(err)
		log.Fatal("DB access failed")
	}
	defer db.Close()

	// ユーザ登録実行
	insert(db, users{name: "nob", age: 13})

	// 複数ユーザ検索実行
	fmt.Println(findByAge(db))

	// 単一ユーザ検索実行
	fmt.Println(findById(db))
}

// データベースに接続します。
func connectDB() (*sql.DB, error) {

	cfg := pq.Config{
		Host:     "localhost",
		Port:     5432,
		User:     "eadbuser",
		Password: "eadbpass",
		Database: "eadb",
		SSLMode:  pq.SSLModeDisable,
		Options:  "-c search_path=eadb",
	}

	c, err := pq.NewConnectorConfig(cfg)
	if err != nil {
		log.Fatal(err)
	}

	db := sql.OpenDB(c)

	// 実際に接続できるかを確認
	err = db.Ping()
	if err != nil {
		return nil, err
	}

	return db, nil
}

// ユーザを登録します。
func insert(db *sql.DB, u users) {

	// クエリ実行
	_, err := db.Exec("INSERT INTO users (name, age) VALUES ($1, $2)", u.name, u.age)
	if err != nil {
		log.Fatal(err)
	}
}

// 30歳未満のユーザ(複数)を検索します。
func findByAge(db *sql.DB) []users {

	rows, err := db.Query("SELECT * FROM users WHERE age < $1", 30) // 30歳未満を抽出
	if err != nil {
		log.Fatal(err)
	}
	defer rows.Close()

	var usersList []users
	for rows.Next() {
		var id int
		var name string
		var age int
		if err := rows.Scan(&id, &name, &age); err != nil {
			log.Fatal(err)
		}
		u := users{id: id, name: name, age: age}
		usersList = append(usersList, u)
	}

	if err := rows.Err(); err != nil {
		log.Fatal(err)
	}

	return usersList
}

// ID=1のユーザ(単一)を検索します。
func findById(db *sql.DB) users {

	row := db.QueryRow("SELECT * FROM users WHERE id = $1", 1) // ID=1を抽出
	var id int
	var name string
	var age int
	row.Scan(&id, &name, &age)

	return users{id, name, age}
}

// usersテーブル向けのモデルです。
type users struct {
	id   int    // ID
	name string // 名前
	age  int    // 年齢
}