0
1

More than 3 years have passed since last update.

GORMをインストールしてPOSTGRESQLと連携するGOのプロジェクトを作成

Last updated at Posted at 2021-03-30

背景

前回はGO言語を使って自分のPCでWEBサーバー構築するという課題でしたが、今回の課題は、データベースを利用してGOから接続したデータを取り出して表示して、WEBサーバーで接続した結果を表示するというものでした。そこで、今回はオブジェクト指向プログラムとリレーショナルデータベースをつなぐ役割をしてくれるGORMを使用して構築していこうと思います。GORMとは、GOのORM(Object-relational mapping)のことをいいます。簡単にいうと、SQL文を書かずにデータベースを使える便利なものと考えてみてください。

プロジェクトを作成してGOからユーザーテーブルを作成

プロジェクト名のフォルダを作成して、その中に入ります。プロジェクト名をcommunicateWithPostgresとします。

mkdir communicateWithPostgres
cd communicateWithPostgres

まずgo mod initでモジュールを初期化します。GOはモジュール形式での開発が可能になったので、GOPATHの設定などは不要です。

go mod init communicateWithPostgres

GORMのPOSTGRESQL用ライブラリ(gorm+driver/postgres)をインストール。sqlite向けのインストールコマンドをpostgres用に書き換えました。

go get -u gorm.io/gorm
go get -u gorm.io/driver/postgres

サンプルコードはこちらを参照

main.go
package main

import (
    "fmt"
    "gorm.io/driver/postgres"
    "gorm.io/gorm"
)

type User struct {
    gorm.Model
    Name  string
    Email string
}

func main() {
    dsn := "host=localhost user=sampleuser dbname=blogapp port=xxxx sslmode=disable TimeZone=Asia/Shanghai"
    db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
    if err != nil {
        panic("failed to connect database")
    }
    db.AutoMigrate(&User{})
    fmt.Println("migrated")
}

GORMの関数であるAutoMigrate関数を使用し名前(Name)とEメール(Email)を持ったユーザーテーブルを作成します。頭文字が大文字のものはPublic、頭文字が小文字のものはPrivateなのでカラム(列)名を大文字にしています。下記のコマンドを入力して、ビルドして実行してみます。

go build main.go && ./main

その結果がこちらになります。

migrated

DBの中身を確認してみます。例として、私の環境では下記のコマンドでPOSTGRESQLにログインしております。(xxxxはDBのポート番号に合わせて変更して下さい。)

Applications/Postgres.app/Contents/Versions/13/bin/psql -pxxxx "blogapp"

\dtでテーブル一覧を表示すると期待通りユーザーテーブルが作成されていました。

blogapp=# \dt
        List of relations
 Schema | Name  | Type  |  Owner  
--------+-------+-------+---------
 public | users | table | sampleuser
(1 row)

ユーザーを3名作成して、表示

main.go
package main

import (
    "fmt"
    "gorm.io/driver/postgres"
    "gorm.io/gorm"
)

type User struct {
    gorm.Model
    Name  string
    Email string
}

func main() {
    dsn := "host=localhost user=sampleuser dbname=blogapp port=xxxx sslmode=disable TimeZone=Asia/Shanghai"
    db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
    if err != nil {
        panic("failed to connect database")
    }
    db.AutoMigrate(&User{})
    fmt.Println("migrated")

    var count int64
    db.Model(&User{}).Count(&count)
    if count == 0 {
        db.Create(&User{Name: "user01", Email: "xxxxxx@xxx01.com"})
        db.Create(&User{Name: "user02", Email: "xxxxxx@xxx02.com"})
        db.Create(&User{Name: "user03", Email: "xxxxxx@xxx03.com"})
    }

    var user User
    db.First(&user)
    fmt.Println(user)
}

要所の説明をしていきます

var count int64 // レコードの数を入れる変数
db.Model(&User{}).Count(&count) // ユーザーのテーブルのレコード数をカウントし、結果がcount変数に入る
if count == 0 { // レコードが0の場合下記3名が作成されます
    db.Create(&User{Name: "user01", Email: "xxxxxx@xxx01.com"})
    db.Create(&User{Name: "user02", Email: "xxxxxx@xxx02.com"})
    db.Create(&User{Name: "user03", Email: "xxxxxx@xxx03.com"})
}

POSTGRESQL上ではこの段階でcount変数が3になっています。select * from users;のコマンドでテーブル内のレコード(行)を表示してみます。3名の名前とEメールが表示されました。再度、レコードを表示させようと試みても、count変数の値が3になっているので、テーブルの情報は更新されません。

blogapp=# select * from users;
 id |          created_at           |          updated_at           | deleted_at |  name  |      email       
----+-------------------------------+-------------------------------+------------+--------+------------------
  1 | 2021-03-27 16:31:58.707403+09 | 2021-03-27 16:31:58.707403+09 |            | user01 | xxxxxx@xxx01.com
  2 | 2021-03-27 16:31:58.709548+09 | 2021-03-27 16:31:58.709548+09 |            | user02 | xxxxxx@xxx02.com
  3 | 2021-03-27 16:31:58.710747+09 | 2021-03-27 16:31:58.710747+09 |            | user03 | xxxxxx@xxx03.com
(3 rows)

条件に一致した最初のレコードを取得します。Where句を使用することでデータベースに保存された大量のデータの中からレコードを検索することが可能になります。

var user User
    db.Where(User{Name: "user02"}).First(&user)
    fmt.Println(user)

ビルドして実行してみると、migratedとuser02が表示されました。

migrated
{{2 2021-03-27 16:31:58.709548 +0900 JST 2021-03-27 16:31:58.709548 +0900 JST {0001-01-01 00:00:00 +0000 UTC false}} user02 xxxxxx@xxx02.com}

以下の書き方もあります。カウントのエラー処理を追加しました。

main.go
package main

import (
    "fmt"

    "gorm.io/driver/postgres"
    "gorm.io/gorm"
)

type User struct {
    gorm.Model
    Name  string
    Email string
}

func main() {
    dsn := "host=localhost user=umehara dbname=blogapp port=5432 sslmode=disable TimeZone=Asia/Tokyo"

    db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
    if err != nil {
        panic("failed to open database")
    }

    db.AutoMigrate(&User{})
    fmt.Println("migrated")

    var count int64
    if err = db.Model(&User{}).Count(&count).Error; err != nil {
        panic("failed to count user table")
    }
    fmt.Println(count)
    if count == 0 {
        db.Create(&User{Name: "user01", Email: "xxxxxx@xxx01.com"})
        db.Create(&User{Name: "user02", Email: "xxxxxx@xxx02.com"})
        db.Create(&User{Name: "user03", Email: "xxxxxx@xxx03.com"})
    }
    var user User
    db.Where(User{Name: "user02"}).First(&user)
    fmt.Println(user)
}

参考
- MySQLとPostgreSQLコマンド比較表

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1