#はじめに
転職にあたりgo言語を使用することになったので勉強して2日くらいです。
書き方なんとなくだけど分かったので、文字読むより手を動かそうと思い、いきなりDB接続しようとしたらめちゃ時間かかった(当たり前)のでその備忘録です。
間違いや、よろしくない書き方などあったらぜひぜひコメントで教えていただけると嬉しいです。
とにかくDBつないで動かしてみることが目的なので実用的ではないかもしれません。
#環境
GOやMYSQLの環境構築は割愛。調べればたくさん出てきます。
OS: windows
go version: go1.17.1 windows/amd64
mysql version: Ver 8.0.26 for Win64 on x86_64 (MySQL Community Server - GPL)
#GORMとは
GO言語のORMライブラリです。公式がとても分かりやすい
##ORMとは
Object-relational mapping
の略です。
名前の通り、オブジェクト(オブジェクト指向におけるオブジェクト)と関係(RDB)とのマッピングを行うものです。
超簡単に言うと、SQLを直接書かなくていいやつ。
詳しく知りたい方は調べてみてください。
#インストール
#gorm
$ go get -u github.com/jinzhu/gorm
# mysql
$ go get -u github.com/go-sql-driver/mysql
#MYSQLに接続
ひとまずCRUDは置いておいて接続を先にしてみます。
以下のように記述しました。go runで走らせてエラーが出なければ接続ができているはずです。
package main
import (
"fmt"
"log"
"time"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
const (
DBMS = "mysql"
DB_USER = "ユーザー名"
DB_PASS = "パスワード"
DB_PROTOCOL = "tcp(127.0.0.1:3306)"
DB_NAME = "DB名"
)
func connectGorm() *gorm.DB {
connectTemplate := "%s:%s@%s/%s?parseTime=True"
connect := fmt.Sprintf(connectTemplate, DB_USER, DB_PASS, DB_PROTOCOL, DB_NAME)
db, err := gorm.Open(DBMS, connect)
if err != nil {
log.Println(err.Error())
}
return db
}
func main() {
db := connectGorm()
defer db.Close()
}
##connectGorm()について捕捉
接続の設定は以下のように書きます
db, err := gorm.Open("mysql", "ユーザー名:パスワード@/DB名")
if err != nil {
panic(err.Error())
}
return db
ユーザー名等は一括管理したいなと思い、constで定義してフォーマットさせました。ymlファイル的なの作りたいけどディレクトリ構造とかわからないのでそれはおいおい。。。
MySQLだと文字コードの問題で?parseTime=true
を末尾につける必要があるらしいのでつけました。
#テーブル定義
テーブルを定義してマイグレーションしたら作ってくれるらしい。
構造体でテーブルの構造を定義します。たぶんentity的な感じ。プロジェクト情報を持つテーブルを作ってみます。
以下を追加
type Projects struct {
gorm.Model
Name string `gorm:"size:50"`
Detail string `gorm:"size:255"`
}
func main() {
~略~
db.Set("gorm:table_options", "ENGINE = noDB").AutoMigrate(&Projects{})
カラム名にあたる部分はパスカルケースで書かないと認識してくれなかったので注意が必要です。DBではスネークケースで登録されます。(例:UserId → user_id)
db.Set("gorm:table_options", "ENGINE = noDB").AutoMigrate(&Projects{})
でテーブルが存在しない時に対象のテーブルを作成してくれます。
実行後にDBを確認するとテーブルが作られています。
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | int unsigned | NO | PRI | NULL | auto_increment |
| created_at | datetime | YES | | NULL | |
| updated_at | datetime | YES | | NULL | |
| deleted_at | datetime | YES | MUL | NULL | |
| name | varchar(50) | YES | | NULL | |
| detail | varchar(255) | YES | | NULL | |
+------------+--------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)
以下のカラムは自動で追加されました。
id
created_at
updated_at
deleted_at
これはgorm.Model
を使用したためです。Model
の中身を見てみると自動追加されている4つの項目が書かれていました。
package gorm
import "time"
// Model base model definition, including fields `ID`, `CreatedAt`, `UpdatedAt`, `DeletedAt`, which could be embedded in your models
// type User struct {
// gorm.Model
// }
type Model struct {
ID uint `gorm:"primary_key"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time `sql:"index"`
}
#CRUD操作
テーブルができたのでCRUDの操作をしてみましょう。
##CREATE
insert
の関数を追加します。
func insert(projects []Projects, db *gorm.DB) {
for _, project := range projects {
db.Create(&project)
}
}
実際にinsertするときは以下のように使用します。
project := Projects{Name: "プロジェクト名", Detail: "詳細"}
insertProjects := []Projects{project}
insert(insertProjects, db)
##READ
###全件取得
func findAll(db *gorm.DB) []Projects {
var allProjects []Projects
db.Find(&allProjects)
return allProjects
}
###指定したIDのデータを取得
func findByID(db *gorm.DB, id int) Projects {
var project Projects
db.First(&project, id)
return project
}
引数でIDを渡して検索しています。
存在しない場合は初期値が返ってきます。
###指定した名前のデータを取得
func findByName(db *gorm.DB, name string) []Projects {
var project []Projects
db.Where("name = ?", name).Find(&project)
return project
}
IDと同じような書き方です。where
とfind
を合わせて使っています。
ヒットしたものをすべて返します。
##UPDATE
###IDをキーに更新
func updateWhereID(id int, newName string, db *gorm.DB) {
var project Projects
db.Model(&project).Where("id = ?", id).Update("name", newName)
}
##DELETE
###IDをキーに削除
func deleteByID(id int, db *gorm.DB) {
var project Projects
db.Where("id = ?", id).Delete(project)
}
####捕捉
gorm.Model
を使用していてdeleted_at
カラムが存在する場合は、deleted_at
に時間が追加されて取得されなくなります。つまり**倫理削除(UPDATE)**されます。
deleted_at
カラムがない場合は物理削除されます。
#参考サイト
https://gorm.io/ja_JP/docs/create.html
gormを使ってローカル環境のMySQLとCRUD操作
Gormを触ってみた(MySQL)
#さいごに
2日目にしてはまあできたほうなんじゃないでしょうか。
とにかく動くことだけを目的に作ったのでもっとMVCライクな感じに書きたいです。いい記事がなかなか見つからず、古い記事を参考に、公式を見ながら直しつつ書いたのであまりにひどかったらコメントください。。
次回は整理してファイル分けしたり、GIN使ってJSONで返すようにしたりしてみたいです。
さいごまで読んでいただきありがとうございます!